题意:
TOP是将某个人移至队首
QUERY是某个人的位置
RANK就是找出第K位是多少
题解;
splay来维护。
先离散化,然后记录每个区间的信息,然后用splay维护一下。
top:先删除再插到队首。
query:找到树中对应的节点,然后旋转到根,然后输出左边大小加1
rank:通过size查找即可,注意每个点的size是区间长度、
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef pair<int,int>P; 5 #define ___ freopen("d:\\acm\\input.txt","r",stdin); 6 const int N=2e5+7; 7 int _t,nd_ed; 8 P ask[N]; 9 int t,n,q,cas,hsh[N],h_ed; 10 map<int,int>mp; 11 struct node 12 { 13 int key,sz; 14 }nd[N]; 15 struct tree 16 { 17 int key,sz,num,f,ch[2]; 18 }T[N]; 19 20 struct Splay_tree 21 { 22 int root; 23 void init(){root=0;} 24 inline void nw(int &x,int f,int loc) 25 { 26 T[++_t].f=f,T[_t].key=nd[loc].key; 27 T[_t].sz=T[_t].num=nd[loc].sz; 28 T[_t].ch[0]=T[_t].ch[1]=0; 29 x=_t; 30 mp[nd[loc].key]=_t; 31 } 32 inline void up(int x){T[x].sz=T[T[x].ch[0]].sz+T[T[x].ch[1]].sz+T[x].num;} 33 inline void rotate(int x){ 34 int y=T[x].f,w=T[y].ch[1]==x; 35 T[y].ch[w]=T[x].ch[w^1]; 36 if(T[x].ch[w^1])T[T[x].ch[w^1]].f=y; 37 if(T[y].f){ 38 int z=T[y].f; 39 if(T[z].ch[0]==y)T[z].ch[0]=x; 40 if(T[z].ch[1]==y)T[z].ch[1]=x; 41 } 42 T[x].f=T[y].f,T[x].ch[w^1]=y,T[y].f=x;up(y); 43 } 44 inline void splay(int x,int w){ 45 int s=1,i=x,y; 46 while(T[x].f!=w){ 47 y=T[x].f; 48 if(T[y].f!=w)(T[T[y].f].ch[0]==y)^(T[y].ch[0]==x)?rotate(x):rotate(y); 49 rotate(x); 50 } 51 if(!w)root=x; 52 up(x); 53 } 54 int build(int &x,int l,int r,int fa=0) 55 { 56 int mid=l+r>>1; 57 nw(x,fa,mid); 58 if(l<mid)build(T[x].ch[0],l,mid-1,x); 59 if(r>mid)build(T[x].ch[1],mid+1,r,x); 60 up(x); 61 return x; 62 } 63 inline void det(int x)//删除下标为x的节点 64 { 65 if(!x)return; 66 splay(x,0); 67 int y=T[x].ch[0],z=T[x].ch[1]; 68 while(T[y].ch[1])y=T[y].ch[1]; 69 while(T[z].ch[0])z=T[z].ch[0]; 70 if(!y&&!z)root=0; 71 else if(!y)splay(z,0),T[z].ch[0]=0,up(z); 72 else if(!z)splay(y,0),T[y].ch[1]=0,up(y); 73 else splay(y,0),splay(z,y),T[z].ch[0]=0,up(z),up(y); 74 } 75 inline void ins_head(int &r,int loc,int x) 76 { 77 if(!r) 78 { 79 T[++_t].f=x,T[_t].key=loc,T[_t].ch[0]=T[_t].ch[1]=0; 80 T[_t].num=T[_t].sz=1,mp[loc]=_t; 81 r=_t; 82 return; 83 } 84 ins_head(T[r].ch[0],loc,r); 85 up(x); 86 } 87 inline int rk(int k) 88 { 89 int r=root,t; 90 while(1) 91 { 92 t=T[T[r].ch[0]].sz; 93 if(k<=t)r=T[r].ch[0]; 94 else if(k<=t+T[r].num)return T[r].key+k-t-1; 95 else k-=t+T[r].num,r=T[r].ch[1]; 96 } 97 } 98 }spt; 99 //-------------------------------- 100 int main() 101 { 102 scanf("%d",&t); 103 while(t--) 104 { 105 scanf("%d%d",&n,&q); 106 char cmd[10]; 107 mp.clear(),_t=0; 108 F(i,1,q) 109 { 110 scanf("%s%d",cmd,&ask[i].second); 111 if(cmd[0]=='T')ask[i].first=1; 112 else if(cmd[0]=='Q')ask[i].first=2; 113 else ask[i].first=3; 114 } 115 h_ed=1,hsh[1]=0,nd_ed=0; 116 F(i,1,q)if(ask[i].first<3)hsh[++h_ed]=ask[i].second; 117 hsh[++h_ed]=n; 118 sort(hsh+1,hsh+1+h_ed); 119 F(i,2,h_ed) 120 { 121 if(hsh[i]!=hsh[i-1]) 122 { 123 if(hsh[i]>hsh[i-1]+1) 124 { 125 nd[++nd_ed].key=hsh[i-1]+1; 126 nd[nd_ed].sz=hsh[i]-hsh[i-1]-1; 127 } 128 nd[++nd_ed].key=hsh[i]; 129 nd[nd_ed].sz=1; 130 } 131 } 132 spt.build(spt.root,1,nd_ed); 133 printf("Case %d:\n",++cas); 134 F(i,1,q) 135 { 136 if(ask[i].first==1) 137 { 138 spt.det(mp[ask[i].second]); 139 spt.ins_head(spt.root,ask[i].second,0); 140 spt.splay(_t,0); 141 }else if(ask[i].first==2) 142 { 143 spt.splay(mp[ask[i].second],0); 144 printf("%d\n",1+T[T[spt.root].ch[0]].sz); 145 }else printf("%d\n",spt.rk(ask[i].second)); 146 } 147 } 148 return 0; 149 }