一开始,直接无脑的对n数组维护。打完之后一看n的范围,默默的删了。
一看范围,就知道要先读进来询问,把涉及到的x做一个统计,这样n的数组
1,2,...,n
(1,x0-1),x0,(x0+1,x1),x1,...,n
这样子就缩好了(一个节点是一个区间)。记录每个节点的起始数。
统计的信息,区间和(即数的个数)。
这样三个操作都能写啦。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <map> 6 #include <set> 7 8 #define KT ch[ch[root][1]][0] 9 #define LC ch[x][0] 10 #define RC ch[x][1] 11 #define N 310001 12 using namespace std; 13 14 struct node{ 15 char op[10]; 16 int x; 17 void in(){ 18 scanf("%s%d",op,&x); 19 } 20 }; 21 struct SplayTree{ 22 int root; 23 int fa[N]; 24 int ch[N][2]; 25 int sz[N]; 26 int top1; 27 int top2; 28 int ss[N]; 29 int que[N]; 30 31 void pushdown(int x){ 32 33 } 34 void pushup(int x){ 35 sz[x]=1+sz[LC]+sz[RC]; 36 sum[x]=val[x]+sum[LC]+sum[RC]; 37 } 38 void rotate(int x,bool f){ 39 int y=fa[x]; 40 int z=fa[y]; 41 pushdown(y); 42 pushdown(x); 43 ch[y][!f]=ch[x][f]; 44 fa[ch[x][f]]=y; 45 fa[x]=z; 46 if (z) { 47 ch[z][ch[z][1]==y] = x; 48 } 49 ch[x][f] = y; 50 fa[y]=x; 51 pushup(y); 52 } 53 void splay(int x, int g) { 54 int y = fa[x]; 55 pushdown(x); 56 while(y!=g){ 57 int z= fa[y]; 58 bool f = (ch[y][0]==x); 59 if(z != g && f == (ch[z][0]==y)){ 60 rotate(y,f); 61 } 62 rotate(x,f); 63 y=fa[x]; 64 } 65 pushup(x); 66 if(g==0) root = x; 67 } 68 void rotateTo(int k,int g) { 69 int x=root; 70 pushdown(x); 71 while(sz[LC] != k){ 72 if(k<sz[LC]){ 73 x=LC; 74 }else{ 75 k -= sz[LC] + 1; 76 x = RC; 77 } 78 pushdown(x); 79 } 80 splay(x,g); 81 } 82 void build(int l,int r,int f){ 83 if(l>r){ 84 return ; 85 } 86 int x = (l + r) >> 1; 87 LC = (x - 1 >= l)? (x - 1 + l)>> 1 :0; 88 RC = (r >= x + 1)? (x + 1 + r)>> 1 :0; 89 fa[x] = f; 90 build(l,x - 1,x); 91 build(x + 1,r,x); 92 pushup(x); 93 } 94 void erase(int x){ 95 if(x==0) 96 return; 97 int father= fa[x]; 98 int head = 0, tail=0; 99 for(que[tail++] =x ; head < tail; head++){ 100 ss[top2++] = que[head]; 101 if(ch[que[head]][0]){ 102 que[tail++]=ch[que[head]][0]; 103 } 104 if(ch[que[head]][1]){ 105 que[tail++] = ch[que[head]][1]; 106 } 107 } 108 ch[father][ch[father][1]==x]=0; 109 pushup(father); 110 } 111 void treaval(int x){ 112 if (x) { 113 pushdown(x); 114 treaval(LC); 115 printf("@%d",val[x]); 116 //ans[cnt++]=val[x]; 117 treaval(RC); 118 } 119 } 120 void newNode(int &x,int c,int r,int st){ 121 if(top2){ 122 x = ss[--top2]; 123 } else { 124 x = ++top1; 125 } 126 LC = RC = fa[x] =0; 127 sz[x] = 1; 128 val[x] = c; 129 ret[x] = r; 130 start[x]=st; 131 132 if(r&&pos.find(r)==pos.end()){ 133 pos[r]=x; 134 } 135 136 } 137 void makeTree(int &x, int l, int r, int f){ 138 if(l > r){ 139 return; 140 } 141 int m=(l+r)>>1; 142 143 newNode(x, num[m], m%2?a[m/2]:0,b[m]); 144 makeTree(LC,l,m-1,x); 145 makeTree(RC,m+1,r,x); 146 fa[x]=f; 147 pushup(x); 148 } 149 void debug(){ 150 treaval(root); 151 cout<<endl; 152 } 153 void cutTo(int l,int r,int c){ 154 rotateTo(l-1,0); 155 rotateTo(r+1,root); 156 //debug(); 157 int tmp=KT; 158 KT=0; 159 pushup(ch[root][1]); 160 pushup(root); 161 rotateTo(c,0); 162 rotateTo(c+1,root); 163 fa[tmp]=ch[root][1]; 164 KT=tmp; 165 pushup(ch[root][1]); 166 pushup(root); 167 //debug(); 168 } 169 int find(int x,int k){ 170 if(sum[LC]<=k-1&&sum[LC]+val[x]>=k){ 171 return start[x]+k-sum[LC]-1; 172 } 173 else if(sum[LC]>=k){ 174 return find(LC,k); 175 }else { 176 return find(RC,k-sum[LC]-val[x]); 177 } 178 } 179 void init(int n,int m){ 180 pos.clear(); 181 top1=top2=root=0; 182 newNode(root,0,0,0); 183 newNode(ch[root][1],0,0,0); 184 fa[ch[root][1]]=root; 185 for(int i=0;i<m;i++) 186 { 187 Q[i].in(); 188 aa[i]=Q[i].x; 189 } 190 sort(aa,aa+m); 191 a[0]=aa[0]; 192 int cnt=1; 193 for(int i=1;i<m;i++){ 194 if(aa[i]!=aa[i-1]) 195 a[cnt++]=aa[i]; 196 } 197 m=cnt; 198 num[0]=a[0]-1; 199 b[0]=1; 200 for(int i=0;i<m;i++){ 201 if(i!=0){ 202 num[i*2]=a[i]-a[i-1]-1; 203 b[i*2]=a[i-1]+1; 204 } 205 num[i*2+1]=1; 206 b[i*2+1]=a[i]; 207 } 208 num[m*2]=n-a[m-1]; 209 b[m*2]=a[m-1]+1; 210 makeTree(KT,0,2*m,ch[root][1]); 211 pushup(ch[root][1]); 212 pushup(root); 213 } 214 void top(int v){ 215 int x=pos[v]; 216 splay(x,0); 217 int k=sz[ch[root][0]]; 218 219 cutTo(k,k,0); 220 } 221 int rank(int k){ 222 223 return find(root,k); 224 } 225 int query(int v){ 226 int x=pos[v]; 227 splay(x,0); 228 //debug(); 229 return sum[LC]+1; 230 } 231 void solve(int m){ 232 233 int v; 234 for(int i=0;i<m;i++){ 235 // debug(); 236 v=Q[i].x; 237 if(Q[i].op[0]==‘T‘){ 238 top(v); 239 }else if(Q[i].op[0]==‘R‘){ 240 printf("%d\n",rank(v)); 241 }else{ 242 printf("%d\n",query(v)); 243 } 244 } 245 } 246 int val[N];//数值 247 int sum[N]; 248 int ret[N];//结果 249 int start[N];//该区间开始的数; 250 251 int aa[N]; 252 int a[N]; 253 int b[N]; 254 int num[N]; 255 //int pos[N]; 256 map<int,int>pos; 257 node Q[N]; 258 }spt; 259 260 int main() 261 { 262 int T; 263 cin>>T; 264 int n,m; 265 int cas=1; 266 while(T--){ 267 scanf("%d%d",&n,&m); 268 printf("Case %d:\n",cas++); 269 spt.init(n,m); 270 spt.solve(m); 271 } 272 return 0; 273 }
时间: 2024-10-24 04:32:10