bzoj4631: 踩气球
被神仙Rose_max踩爆了这个离线我就会啊
把每个区间在线段树上分裂开,然后当一个区间空了就给那个孩子--,每个区间都变成0答案就++
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<vector> #define lc (now<<1) #define rc (now<<1|1) #define mid (ql+qr)/2 using namespace std; const int _=1e2; const int maxn=1e5+_; const int maxm=1e5+_; const int mbit=(1<<17)+_; int n,w[maxn],m,hap,num[maxm]; //---------------------------------------------def-------------------------------------------- struct segnode{int s;vector<int>v;}; struct segtree { segnode tr[mbit*2]; void update(int now){tr[now].s=tr[lc].s+tr[rc].s;} void bt(int now,int ql,int qr) { if(ql==qr) { tr[now].s+=w[ql]; return ; } bt(lc,ql,mid); bt(rc,mid+1,qr); update(now); } void spilit(int now,int ql,int qr,int l,int r,int id) { if(ql==l&&qr==r) { num[id]++; tr[now].v.push_back(id); return ; } if(r<=mid) spilit(lc,ql,mid,l,r,id); else if(mid+1<=l)spilit(rc,mid+1,qr,l,r,id); else spilit(lc,ql,mid,l,mid,id),spilit(rc,mid+1,qr,mid+1,r,id); } void reduce(int now,int ql,int qr,int p) { tr[now].s--; if(tr[now].s==0) { for(int i=0;i<tr[now].v.size();i++) { int x=tr[now].v[i]; num[x]--;if(num[x]==0)hap++; } } if(ql==qr){return ;} if(p<=mid)reduce(lc,ql,mid,p); else reduce(rc,mid+1,qr,p); } }seg; //---------------------------------------------data structure-------------------------------------------- int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&w[i]); seg.bt(1,1,n); int x,y; for(int i=1;i<=m;i++) scanf("%d%d",&x,&y),seg.spilit(1,1,n,x,y,i); int Q; scanf("%d",&Q); while(Q--) { scanf("%d",&x); x=(x+hap-1)%n+1; seg.reduce(1,1,n,x); printf("%d\n",hap); } return 0; }
pain and happy in the cruel world.