bzoj1503: [NOI2004]郁闷的出纳员(伸展树)
1503: [NOI2004]郁闷的出纳员
题目:传送门
题解:
修改操作一共不超过100
直接暴力在伸展树上修改
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 struct node 8 { 9 int d,c,n,f,son[2]; 10 }tr[110000];int len,root,ans; 11 void add(int d,int f) 12 { 13 len++;tr[len].d=d;tr[len].n=tr[len].c=1; 14 tr[len].son[0]=tr[len].son[1]=0;tr[len].f=f; 15 if(d<tr[f].d)tr[f].son[0]=len; 16 else tr[f].son[1]=len; 17 } 18 void update(int x) 19 { 20 int lc=tr[x].son[0],rc=tr[x].son[1]; 21 tr[x].c=tr[lc].c+tr[rc].c+tr[x].n; 22 } 23 int findip(int d) 24 { 25 int x=root; 26 while(tr[x].d!=d) 27 { 28 if(d<tr[x].d) 29 { 30 if(tr[x].son[0]==0)break; 31 else x=tr[x].son[0]; 32 } 33 else 34 { 35 if(tr[x].son[1]==0)break; 36 else x=tr[x].son[1]; 37 } 38 } 39 return x; 40 } 41 void rotate(int x,int w) 42 { 43 int f=tr[x].f,ff=tr[f].f; 44 int r,R; 45 r=tr[x].son[w],R=f; 46 tr[R].son[1-w]=r; 47 if(r!=0)tr[r].f=R; 48 49 r=x,R=ff; 50 if(tr[R].son[0]==f)tr[R].son[0]=r; 51 else tr[R].son[1]=r; 52 tr[r].f=R; 53 54 r=f,R=x; 55 tr[R].son[w]=r; 56 tr[r].f=R; 57 58 update(f);update(x); 59 } 60 void splay(int x,int rt) 61 { 62 while(tr[x].f!=rt) 63 { 64 int f=tr[x].f,ff=tr[f].f; 65 if(ff==rt) 66 { 67 if(tr[f].son[0]==x)rotate(x,1); 68 else rotate(x,0); 69 } 70 else 71 { 72 if(tr[ff].son[0]==f && tr[f].son[0]==x)rotate(f,1),rotate(x,1); 73 else if(tr[ff].son[1]==f && tr[f].son[1]==x)rotate(f,0),rotate(x,0); 74 else if(tr[ff].son[1]==f && tr[f].son[0]==x)rotate(x,1),rotate(x,0); 75 else if(tr[ff].son[0]==f && tr[f].son[1]==x)rotate(x,0),rotate(x,1); 76 } 77 } 78 if(rt==0)root=x; 79 } 80 void ins(int d) 81 { 82 if(root==0) 83 { 84 add(d,0);root=len; 85 return ; 86 } 87 int x=findip(d); 88 if(tr[x].d==d) 89 { 90 tr[x].n++; 91 update(x); 92 splay(x,0); 93 } 94 else 95 { 96 add(d,x); 97 update(x); 98 splay(len,0); 99 } 100 } 101 void del(int d) 102 { 103 int x=findip(d);if(tr[x].d!=d)return ; 104 ans+=tr[x].n;splay(x,0); 105 if(tr[x].son[0]==0 && tr[x].son[1]==0){root=0;len=0;} 106 else if(tr[x].son[0]!=0 && tr[x].son[1]==0){root=tr[x].son[0];tr[root].f=0;} 107 else if(tr[x].son[0]==0 && tr[x].son[1]!=0){root=tr[x].son[1];tr[root].f=0;} 108 else 109 { 110 int p=tr[x].son[0]; 111 while(tr[p].son[1]!=0)p=tr[p].son[1]; 112 splay(p,x); 113 114 int r=tr[x].son[1],R=p; 115 tr[R].son[1]=r; 116 tr[r].f=R; 117 118 root=p;tr[root].f=0; 119 update(root); 120 } 121 } 122 void findshuzi(int k) 123 { 124 int x=root; 125 while(1) 126 { 127 int lc=tr[x].son[0],rc=tr[x].son[1]; 128 if(k<=tr[lc].c)x=lc; 129 else if(k>tr[lc].c+tr[x].n)k-=tr[lc].c+tr[x].n,x=rc; 130 else break; 131 } 132 printf("%d\n",tr[x].d); 133 } 134 int n,m,sum,sc[110000]; 135 void jia(int x,int k) 136 { 137 tr[x].d+=k; 138 if(tr[x].son[0]!=0)jia(tr[x].son[0],k); 139 if(tr[x].son[1]!=0)jia(tr[x].son[1],k); 140 } 141 void jian(int x,int k) 142 { 143 tr[x].d-=k;if(tr[x].d<m)sc[++sum]=x; 144 if(tr[x].son[0]!=0)jian(tr[x].son[0],k); 145 if(tr[x].son[1]!=0)jian(tr[x].son[1],k); 146 } 147 char st[2]; 148 int main() 149 { 150 scanf("%d%d",&n,&m);ans=0; 151 len=0;root=0; 152 for(int i=1;i<=n;i++) 153 { 154 sum=0; 155 int x;scanf("%s%d",st+1,&x); 156 if(st[1]=='I') 157 { 158 if(x<m)continue; 159 ins(x); 160 } 161 else if(st[1]=='A')jia(root,x); 162 else if(st[1]=='S') 163 { 164 jian(root,x); 165 for(int j=1;j<=sum;j++)del(tr[sc[j]].d); 166 } 167 else 168 { 169 if(tr[root].c<x)printf("-1\n"); 170 else findshuzi(tr[root].c-x+1); 171 } 172 } 173 printf("%d\n",ans); 174 return 0; 175 }