bzoj 1503: [NOI2004]郁闷的出纳员
惭愧。。。
1 #include<cstdio> 2 const int maxn=200010; 3 int lim; 4 struct splaytree 5 { 6 int sz[maxn]; 7 int ch[maxn][2]; 8 int pre[maxn]; 9 int rt,top; 10 inline void up(int x) 11 { 12 sz[x]=cnt[x]+sz[ch[x][0]]+sz[ch[x][1]]; 13 } 14 inline void rotate(int x,int f) 15 { 16 int y=pre[x]; 17 ch[y][!f]=ch[x][f]; 18 pre[ch[x][f]]=y; 19 pre[x]=pre[y]; 20 if(pre[x]) ch[pre[y]][ch[pre[y]][1]==y]=x; 21 ch[x][f]=y; 22 pre[y]=x; 23 up(y); 24 } 25 inline void splay(int x,int goal) 26 { 27 while(pre[x]!=goal) 28 { 29 if(pre[pre[x]]==goal) rotate(x,ch[pre[x]][0]==x); 30 else 31 { 32 int y=pre[x],z=pre[y]; 33 int f=(ch[z][0]==y); 34 if(ch[y][f]==x) rotate(x,!f),rotate(x,f); 35 else rotate(y,f),rotate(x,f); 36 } 37 } 38 up(x); 39 if(goal==0) rt=x; 40 } 41 inline void RTO(int k,int goal) 42 { 43 int x=rt; 44 while(sz[ch[x][0]]!=k-1) 45 { 46 if(k<sz[ch[x][0]]+1) x=ch[x][0]; 47 else 48 { 49 k-=(sz[ch[x][0]]+1); 50 x=ch[x][1]; 51 } 52 } 53 splay(x,goal); 54 } 55 inline void newnode(int &x,int c) 56 { 57 x=++top; 58 ch[x][0]=ch[x][1]=pre[x]=0; 59 sz[x]=1;cnt[x]=1; 60 val[x]=c; 61 } 62 inline void init() 63 { 64 sum=ch[0][0]=ch[0][0]=pre[0]=sz[0]=0; 65 rt=top=0;cnt[0]=0; 66 } 67 inline void insert(int &x,int key,int f) 68 { 69 if(!x) 70 { 71 newnode(x,key); 72 pre[x]=f; 73 splay(x,0); 74 return ; 75 } 76 if(key==val[x]) 77 { 78 cnt[x]++; 79 sz[x]++; 80 splay(x,0); 81 return ; 82 } 83 else if(key<val[x]) 84 { 85 insert(ch[x][0],key,x); 86 } 87 else 88 { 89 insert(ch[x][1],key,x); 90 } 91 up(x); 92 } 93 inline void del(int &x,int f) 94 { 95 if(!x) return ; 96 if(val[x]>=lim) 97 del(ch[x][0],x); 98 else 99 { 100 sum+=sz[ch[x][0]]+cnt[x]; 101 x=ch[x][1]; 102 pre[x]=f; 103 if(f==0) rt=x; 104 del(x,f); 105 } 106 if(x) up(x); 107 } 108 inline int find_kth(int x,int k) 109 { 110 if(k<sz[ch[x][0]]+1) 111 return find_kth(ch[x][0],k); 112 else if(k>sz[ch[x][0]]+cnt[x]) 113 return find_kth(ch[x][1],k-sz[ch[x][0]]-cnt[x]); 114 else 115 { 116 splay(x,0); 117 return val[x]; 118 } 119 } 120 int cnt[maxn]; 121 int val[maxn]; 122 int sum; 123 }spt; 124 int main() 125 { 126 int n; 127 char com[5]; 128 scanf("%d%d",&n,&lim); 129 int lim0=lim; 130 spt.init(); 131 while(n--) 132 { 133 int k; 134 scanf("%s%d",com,&k); 135 if(com[0]=='I') 136 { 137 if(k<lim0) continue; 138 spt.insert(spt.rt,k+lim-lim0,0); 139 } 140 else if(com[0]=='A') 141 lim-=k; 142 else if(com[0]=='S') 143 { 144 lim+=k; 145 if(spt.sz[spt.rt]>0) spt.del(spt.rt,0); 146 } 147 else 148 { 149 int sz=spt.sz[spt.rt]; 150 if(k>sz) printf("-1\n"); 151 else 152 { 153 printf("%d\n",spt.find_kth(spt.rt,sz-k+1)-lim+lim0); 154 } 155 } 156 } 157 printf("%d\n",spt.sum); 158 return 0; 159 }