hdu 3436 Queue-jumpers(splay)

题目链接:hdu 3436 Queue-jumpers

题意:

TOP是将某个人移至队首

QUERY是某个人的位置

RANK就是找出第K位是多少

题解;
splay来维护。

先离散化,然后记录每个区间的信息,然后用splay维护一下。

top:先删除再插到队首。

query:找到树中对应的节点,然后旋转到根,然后输出左边大小加1

rank:通过size查找即可,注意每个点的size是区间长度、

  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:
",++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
",1+T[T[spt.root].ch[0]].sz);
145             }else printf("%d
",spt.rk(ask[i].second));
146         }
147     }
148     return 0;
149 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/6344656.html