bzoj2527: [Poi2011]Meteors(整体二分)
http://www.lydsy.com/JudgeOnline/problem.php?id=2527
整体二分
区间加,单点查,树状数组维护差分序列
注意 累积可能会爆long long,所以一满足要求就break
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 300001 #define lowbit(x) x&-x typedef long long LL; int m,k; int tot,front[N],nxt[N],to[N]; struct node { bool ty; int l,r,id; int num,cur; }e[N<<1],tmp1[N<<1],tmp2[N<<1]; int need[N],ans[N]; LL have[N]; LL c[N+10]; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } void add(int x,int y) { to[++tot]=y; nxt[tot]=front[x]; front[x]=tot; } void change(int x,int y) { while(x<=m) { c[x]+=y; x+=lowbit(x); } } LL query(int x) { LL sum=0; while(x) { sum+=c[x]; x-=lowbit(x); } return sum; } void solve(int head,int tail,int l,int r) { if(head>tail) return; if(l==r) { for(int i=head;i<=tail;++i) if(!e[i].ty) ans[e[i].l]=l; return; } int mid=l+r>>1; for(int i=head;i<=tail;++i) { if(e[i].ty && e[i].id<=mid) { if(e[i].l<=e[i].r) { change(e[i].l,e[i].num); change(e[i].r+1,-e[i].num); } else { change(e[i].l,e[i].num); change(1,e[i].num); change(e[i].r+1,-e[i].num); } } else if(!e[i].ty) { have[e[i].l]=0; for(int j=front[e[i].l];j;j=nxt[j]) { have[e[i].l]+=query(to[j]); if(have[e[i].l]>=e[i].num) break; } } } for(int i=head;i<=tail;++i) { if(e[i].ty && e[i].id<=mid) { if(e[i].l<=e[i].r) { change(e[i].l,-e[i].num); change(e[i].r+1,e[i].num); } else { change(e[i].l,-e[i].num); change(1,-e[i].num); change(e[i].r+1,e[i].num); } } } int ll=0,rr=0; for(int i=head;i<=tail;++i) { if(!e[i].ty) { if(e[i].cur+have[e[i].l]>=e[i].num) tmp1[++ll]=e[i]; else { e[i].cur+=have[e[i].l]; tmp2[++rr]=e[i]; } } else { if(e[i].id<=mid) tmp1[++ll]=e[i]; else tmp2[++rr]=e[i]; } } for(int i=1;i<=ll;++i) e[head+i-1]=tmp1[i]; for(int i=1;i<=rr;++i) e[head+ll+i-1]=tmp2[i]; solve(head,head+ll-1,l,mid); solve(head+ll,tail,mid+1,r); } int main() { int n; read(n); read(m); int x,y,z; for(int i=1;i<=m;++i) { read(x); add(x,i); } for(int i=1;i<=n;++i) read(need[i]); read(k); for(int i=1;i<=k;++i) { read(e[i].l); read(e[i].r); read(e[i].num); e[i].ty=true; e[i].id=i; } k++; e[k].l=1; e[k].r=m; e[k].num=1e9; e[k].ty=true; e[k].id=k; for(int i=1;i<=n;++i) { e[k+i].l=i; e[k+i].num=need[i]; } solve(1,n+k,1,k); for(int i=1;i<=n;++i) { if(ans[i]==k) puts("NIE"); else cout<<ans[i]<<'\n'; } }