BZOJ1861 [Zjoi2006]Book 书架

从6点调到了现在22:19:07。。脑子晕倒死。

用splay做,一开始怎么想也不知道该怎么play。

想了个办法,用pos[i]表示编号为i的书在树上的节点编号

s[i]表示树上的节点i代表的是哪本书。

val[i]表示节点i的权值,这里的权值按照书从上到下的大小顺序来赋值,用来建树

TOP:先把树里面代表书S的那个节点删掉,然后再重新建一个节点把S放进去,这时候,

    为了使新的节点在最前方,开一个mmin表示已经出现过的最小的数,

    每次要把节点加入进去的时候插入几点的权值就是 --mmin;

BOT:同上;

INSERT:找到S的前驱或后继,然后调换一下顺序就ok

ASK:查询排名

QUERY:查询排名为K的书的编号。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 using namespace std;
  5 const int maxn = 200005;
  6 int fa[maxn],son[2][maxn],val[maxn],pos[maxn],siz[maxn],s[maxn];
  7 int root,tot,mmax,mmin;
  8 void rota(int w,int x){
  9     int y = fa[x];
 10     son[!w][y] = son[w][x];
 11     if(son[w][x])fa[son[w][x]] = y;
 12     fa[x] = fa[y];
 13     if(fa[y])son[y==son[1][fa[y]]][fa[y]] = x;
 14     fa[y] = x;
 15     son[w][x] = y;
 16     siz[y] = siz[y]-siz[x]+siz[son[!w][y]];
 17     siz[x] = siz[x]-siz[son[!w][y]]+siz[y];
 18 }
 19 void splay(int x,int y){
 20     while(fa[x]!=y){
 21         if(fa[fa[x]]==y)rota(x==son[0][fa[x]],x);
 22         else {
 23             int w = fa[x]==son[0][fa[fa[x]]];
 24             if(x==son[w][fa[x]]){
 25                 rota(!w,x);rota(w,x);
 26             }
 27             else {
 28                 rota(w,fa[x]);rota(w,x);
 29             }
 30         }
 31     }
 32     if(y==0)root = x;
 33 }
 34 void Ins(int v){
 35     int x = root;
 36     while(1){
 37         siz[x]++;
 38         if(v<val[x]){
 39             if(son[0][x])x = son[0][x];
 40             else break;
 41         }
 42         else {
 43             if(son[1][x])x = son[1][x];
 44             else break;
 45         }
 46     }
 47     fa[++tot] = x;
 48     val[tot] = v;
 49     siz[tot] = 1;
 50     if(v<val[x])son[0][x] = tot;
 51     else son[1][x] = tot;
 52     splay(tot,0);
 53 }
 54 int getPre(int x){
 55     splay(x,0);x = son[0][x];///先把x从根节点拿到子树上
 56     if(!x)return 0;
 57     while(son[1][x])x = son[1][x];
 58     return x;
 59 }
 60 int getNext(int x){
 61     splay(x,0);x = son[1][x];
 62     if(!x)return 0;
 63     while(son[0][x])x = son[0][x];
 64     return x;
 65 }
 66 void Del(int x){
 67     splay(x,0);
 68     int y = getPre(x),z = getNext(x);
 69     if(y==0&&z==0){root = 0;return;}
 70     if(y)splay(y,0);
 71     if(z)splay(z,y);
 72     if(y==0){son[0][z] = 0,siz[z]--;return;}
 73     if(z==0){son[1][y] = 0,siz[y]--;return;}
 74     son[0][z] = 0;
 75     siz[z]--,siz[y]--;
 76 }
 77 int getRank(int x){
 78     splay(x,0);
 79     return siz[son[0][x]];
 80 }
 81 int getK(int k){
 82     int x = root;
 83     while(k!=siz[son[0][x]]+1){
 84         if(k<=siz[son[0][x]])x = son[0][x];
 85         else {
 86             k-=(siz[son[0][x]]+1);///以后千万记得先更新k之后再更新x!!!!
 87             x = son[1][x];
 88         }
 89     }
 90     return s[x];
 91 }
 92 int main()
 93 {
 94     int n,m;scanf("%d%d",&n,&m);
 95     for(int i = 1;i<=n;++i){
 96         int t;scanf("%d",&t);
 97         if(i==1){
 98             root = ++tot;
 99             val[1] = 1;
100             siz[1] = 1;
101             s[1] = t;
102         }
103         else Ins(i);
104         pos[t] = tot;
105         s[tot] = t;
106     }
107     mmin = 1;mmax = n;
108     while(m--){
109         char ss[10];
110         int a,b,x;
111         scanf("%s%d",ss,&a);
112         if(ss[0]=='T'){
113             Del(pos[a]);
114             Ins(--mmin);pos[a] = tot;
115             s[tot] = a;
116         }
117         else if(ss[0]=='B'){
118             Del(pos[a]);Ins(++mmax);
119             pos[a] = tot;
120             s[tot] = a;
121         }
122         else if(ss[0]=='I'){
123             scanf("%d",&b);
124             if(!b)continue;
125             if(b==-1)x = getPre(pos[a]);
126             else x = getNext(pos[a]);
127             x = s[x];
128             swap(pos[a],pos[x]);
129             swap(s[pos[a]],s[pos[x]]);
130         }
131         else if(ss[0]=='A')printf("%d\n",getRank(pos[a]));
132         else printf("%d\n",getK(a));
133     }
134     return 0;
135 }

 

posted on 2015-08-07 22:32  round_0  阅读(323)  评论(0编辑  收藏  举报

导航