询问操作需要搞一下
今天被区间合并降智了
/* D a: 摧毁第a个点 Q a:询问a所在的点的块大小 R :修复最后被破坏的点 对于所有的点需要进行一次更新 更新比较容易,tag用来表示区间是否是完整的 查询时如果pos所在的大块有tag标记,那么直接返回块的大小即可 反之,如果pos在左区间,那就到左区间里去找: 如果pos的位置和rmx[rt<<1]相连,那么答案就是rmx[rt<<1]+lmx[rt<<1|1] 如果不相连,那么递归到左区间里找 如果pos在右区间, 如果pos的位置和lmx[rt<<1|1]相连,那么答案就是rmx[rt<<1]+lmx[rt<<1|1] 如果不相连,那么递归到右区间里找 如果 l==r并且tag==0,那么就是0 */ #include<bits/stdc++.h> using namespace std; #define maxn 50005 int n,m; stack<int>s; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int tag[maxn<<2],mx[maxn<<2],lmx[maxn<<2],rmx[maxn<<2]; void pushup(int l,int r,int rt){ lmx[rt]=lmx[rt<<1],rmx[rt]=rmx[rt<<1|1]; mx[rt]=max(mx[rt<<1],mx[rt<<1|1]); int m=l+r>>1; if(lmx[rt<<1]==m-l+1)lmx[rt]=lmx[rt<<1]+lmx[rt<<1|1]; if(rmx[rt<<1|1]==r-m)rmx[rt]=rmx[rt<<1]+rmx[rt<<1|1]; mx[rt]=max(mx[rt],max(lmx[rt],rmx[rt])); mx[rt]=max(mx[rt],rmx[rt<<1]+lmx[rt<<1|1]); if(mx[rt]!=r-l+1)tag[rt]=0; else tag[rt]=1; } void build(int l,int r,int rt){ tag[rt]=1; if(l==r){mx[rt]=lmx[rt]=rmx[rt]=1;return;} int m=l+r>>1; build(lson);build(rson); pushup(l,r,rt); } void update(int pos,int l,int r,int rt,int val){ if(l==r){mx[rt]=lmx[rt]=rmx[rt]=tag[rt]=val;return;} int m=l+r>>1; if(pos<=m)update(pos,lson,val); else update(pos,rson,val); pushup(l,r,rt); } int query(int pos,int l,int r,int rt){ if(mx[rt]==0)return 0; else if(tag[rt])return mx[rt]; int m=l+r>>1; if(pos<=m){ if(pos>=m-rmx[rt<<1]+1) return query(pos,lson)+lmx[rt<<1|1]; else return query(pos,lson); } else { if(pos<=m+lmx[rt<<1|1]) return query(pos,rson)+rmx[rt<<1]; else return query(pos,rson); } } int main(){ while(cin>>n>>m){ build(1,n,1); while(m--){ char opt[10];int a; cin>>opt; if(opt[0]!='R')cin>>a; if(opt[0]=='D')update(a,1,n,1,0),s.push(a); if(opt[0]=='Q')cout<<query(a,1,n,1)<<' '; if(opt[0]=='R')update(s.top(),1,n,1,1),s.pop(); } } }