/**************************************題目大意:一條直線上的有n個頂點;(1)D x 破壞頂點x;(2)Q x 表示查詢以x所在的最長的連續的點的個數,包括頂點x本身;(3)R 修複上一次被破壞的點;演算法思想:線段樹,求最大連續區間,操作類似於pku3667;ls 記錄區間左端點開始的最大連續個數,rs 記錄區間右端點開始的最大的連續個數,ms 表示該區間最大的連續點的個數。***************************************/#include<iostream>#include<algorithm>#include<stack>#include<cstring>#include<cstdlib>#include<cstdio>using namespace std;#define L l,m,u<<1#define R m+1,r,u<<1|1const int N=50050;int st[N];//類比棧序列int top;//類比棧頂元素struct Node{ int l,r; int ls,rs,ms;//ls:左邊開始連續的最大長度;rs:右邊開始最大的連續長度;ms:這個區間最大連續長度;} T[N*3];void build(int l,int r,int u){ T[u].l=l; T[u].r=r; T[u].ls=T[u].rs=T[u].ms=r-l+1; if(l==r) return; int m=(l+r)>>1; build(L); build(R);}void update(int u,int t,int x){ if(T[u].l==T[u].r) { if(x==1) T[u].ls=T[u].rs=T[u].ms=1; else T[u].ls=T[u].rs=T[u].ms=0; return; } int m=(T[u].l+T[u].r)>>1; if(t<=m) update(u<<1,t,x); else update(u<<1|1,t,x); T[u].ls=T[u<<1].ls; T[u].rs=T[u<<1|1].rs; T[u].ms=max(T[u<<1].ms,T[u<<1|1].ms); T[u].ms=max(T[u].ms,T[u<<1].rs+T[u<<1|1].ls); if(T[u<<1].ls==T[u<<1].r-T[u<<1].l+1) T[u].ls+=T[u<<1|1].ls; if(T[u<<1|1].rs==T[u<<1|1].r-T[u<<1|1].l+1) T[u].rs+=T[u<<1].rs;}int query(int u,int t){ if(T[u].l==T[u].r||T[u].ms==0||T[u].ms==T[u].r-T[u].l+1) { return T[u].ms; } int m=(T[u].l+T[u].r)>>1; if(t<=m) { if(t>=T[u<<1].r-T[u<<1].rs+1) return query(u<<1,t)+query(u<<1|1,m+1); else return query(u<<1,t); } else { if(t<=T[u<<1|1].l+T[u<<1|1].ls-1) return query(u<<1|1,t)+query(u<<1,m); else return query(u<<1|1,t); }}int main(){ //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); int n,m; while(~scanf("%d%d",&n,&m)) { build(1,n,1); top=0; while(m--) { char c; int x; scanf(" %c",&c); if(c=='D') { scanf("%d",&x); st[top++]=x; update(1,x,0); } else if(c=='Q') { scanf("%d",&x); printf("%d\n",query(1,x)); } else { if(x>0) { x=st[--top]; update(1,x,1); } } } } return 0;}