整體二分
阿新 • • 發佈:2018-06-14
tmp define tor end #define font using inline lin
只適用於存在加減性的問題
有時候可以把一維主席樹變成線段樹+整體二分降低難度
一直沒寫過
今天寫了一下
要註意的是
二分有負數的時候
加一句特判
int mid=(h1+t1)/2;
if (h1<=0&&t1<=0) mid=(h1+t1-1)/2;
#include <bits/stdc++.h> using namespace std; #define ll long long #define IL inline #define rint register int #define me(x) memset(x,0,sizeof(x)) #definefi first #define se second //#define mid ((h+t)>>1) #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) #define setit set<int>::iterator char ss[1<<24],*A=ss,*B=ss; IL char gc() { return (A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++); } template<class T>void read(T &x) { rint f=1,c; while (c=gc(),c<48||c>57) if (c==‘-‘) f=-1; x=c^48; while (c=gc(),47<c&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; } char sr[1<<24],z[20]; int C=-1,Z; template <class T> voidwer(T x) { if (x<0) sr[++C]=‘-‘,x=-x; while (z[++Z]=x%10+48,x/=10); while (sr[++C]=z[Z],--Z); sr[++C]=‘\n‘; } template<class T>IL T MAX(T x,T y) { if (x>y) return(x); else return(y); } template<class T>IL T MIN(T x,T y) { if (x<y) return(x); else return(y); } template<class T>IL void SWAP(T &x,T &y) { T tmp=x; x=y; y=tmp; } IL setit prev(register setit it) { register setit it2=it; return(--it2); } IL setit next(register setit it) { register setit it2=it; return(++it2); } const int N=3e5; const int INF=1.1e9; struct re{ int a,b,c,d; }b[N]; int f[N],a[N],ans[N],n,m; #define lowbit(x) (x&(-x)) IL void add(int x,int y) { while (x<=n) { f[x]++; x+=lowbit(x); } } IL int query(int x) { int ans=0; while (x>0) { ans+=f[x]; x-=lowbit(x); } return(ans); } void find(int h,int t,int h1,int t1) { // cout<<h1<<" "<<t1<<endl; if (h>t) return; if (h1==t1) { rep(i,h,t) ans[b[i].d]=h1; return; } memset(f,0,sizeof(f)); int mid=(h1+t1)/2; if (h1<=0&&t1<=0) mid=(h1+t1-1)/2; rep(i,1,n) if (a[i]<=mid&&a[i]>=h1) add(i,1); queue<re> q1,q2; rep(i,h,t) { int ans=query(b[i].b)-query(b[i].a-1); if (ans>=b[i].c) q1.push((re){b[i].a,b[i].b,b[i].c,b[i].d}); else q2.push((re){b[i].a,b[i].b,b[i].c-ans,b[i].d}); } int cnt=h-1; while (!q1.empty()) { re x=q1.front(); q1.pop(); b[++cnt]=x; } find(h,cnt,h1,mid); int cnt2=cnt; while (!q2.empty()) { re x=q2.front(); q2.pop(); b[++cnt]=x; } find(cnt2+1,t,mid+1,t1); } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); read(n); read(m); rep(i,1,n) read(a[i]); rep(i,1,m) { read(b[i].a); read(b[i].b); read(b[i].c); b[i].d=i; } find(1,m,-INF,INF); rep(i,1,m) wer(ans[i]); fwrite(sr,1,C+1,stdout); return 0; }
整體二分