7 9 D 3 D 6 D 5 Q 4 Q 5 R Q 4 R Q 4
1 0 2 4//转载大神的,然后加上自己的理解,不知怎么就错了!#include"stdio.h" #include"string.h" #include"stdlib.h" #include"stack" using namespace std; #define N 50011
int n,m; int hash[N]; struct Segtree { int l,r,mid; int count; }T[4*N];
void build(int l,int r,int k) { T[k].l=l; T[k].r=r; T[k].mid=(l+r)>>1; //叶子节点 if(l==r) { T[k].count=0; return ; } build(l,T[k].mid,2*k); build(T[k].mid+1,r,2*k+1); T[k].count=0; }
int findl(int l,int r,int k) { int ans=0; //左右区间正好等于该节点左右区间 if(T[k].l==l && T[k].r==r && !T[k].count) return r-l+1; //结点为叶子节点 if(T[k].l==T[k].r && T[k].l==l && l==r) return 1-T[k].count; //位于区间左边 if(r<=T[k].mid) ans=findl(l,r,2*k); //位于区间左边 else if(l>T[k].mid) ans=findl(l,r,2*k+1); else { ans=findl(T[k].mid+1,r,2*k+1);//到区间右边搜索 if(ans==r-T[k].mid)///证明该区间为断开,需到中点左边搜索 ans+=findl(l,T[k].mid,2*k); } return ans; }
int findr(int l,int r,int k) { int ans=0; if(T[k].l==l && T[k].r==r && !T[k].count) return r-l+1; if(T[k].l==T[k].r && T[k].l==l && l==r) return 1-T[k].count; if(r<=T[k].mid) ans=findr(l,r,2*k); else if(l>T[k].mid) ans=findr(l,r,2*k+1); else { ans=findr(l,T[k].mid,2*k); if(ans==T[k].mid-l+1) ans+=findr(T[k].mid+1,r,2*k+1); } return ans; }
void Dir(int aim,int dir,int k) { if(T[k].l==T[k].r && T[k].l==aim) { T[k].count+=dir; return ; } if(aim<=T[k].mid) Dir(aim,dir,2*k); else Dir(aim,dir,2*k+1); T[k].count+=dir; //这里不判0了,所以千万要先判一下hash }
int main() { int temp; char str[111]; while(scanf("%d%d",&n,&m)!=-1) { stack<int>st; build(1,n,1); memset(hash,0,sizeof(hash)); while(m--) { scanf("%s",str); if(str[0]!='R') { scanf("%d",&temp); if(str[0]=='D') { st.push(temp); if(hash[temp]) continue; //注意,hash亮了的话,说明被del了 else { hash[temp]=1; Dir(temp,1,1); } } else if(str[0]=='Q') { if(hash[temp]) printf("0\n"); else { //用左右分别查找吧 int a,b; a=findl(1,temp,1); b=findr(temp,n,1); printf("%d\n",a+b-1); } } } else { if(!st.empty()) { temp=st.top(); st.pop(); if(!hash[temp]) continue; hash[temp]=0; Dir(temp,-1,1); } } } } return 0; }