hdu 2475 BOX (splay)

hdu 2475node

Splay樹是一種神奇的東西。。。
ios

題意:spa

  有一些箱子,要麼放在地上,要麼放在某個箱子裏面 。code

  如今有兩種操做:blog

    (1) MOVE x y: 把 x 號箱子放到 y 號箱子裏面,操做不合法就忽略這一次操做 。get

    (2) QUERY x :  查詢 x 號箱子最外面的箱子是哪個string

解法:it

  首先對全部的樹進行一遍DFS,獲得一個DFS序,能夠把它當作是一個括號序列,開始訪問某個節點是左括號,結束訪問時是右括號 。這樣這題就轉換成用Splay樹來維護這個序列 。io

  對於MOVE操做:

    將 x 對應那一段序列切下來,並將其放到 y 對應左括號的右邊 。

  對於QUERY操做:

    直接查詢以 x 爲根的子樹的最小值 。

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cmath>
  5 #include <cstring>
  6 #include <queue>
  7 #include <set>
  8 #include <vector>
  9 #include <map>
 10 #define ll long long
 11 
 12 using namespace std;
 13 
 14 const int N=50007;
 15 
 16 //  前向星
 17 struct edge{
 18     int to,nex;
 19 }e[N];
 20 int cnt;
 21 int head[N];
 22 
 23 inline void addedge(int u,int v){
 24     e[cnt].to=v; 
 25     e[cnt].nex=head[u];
 26     head[u]=cnt++;
 27 }
 28 
 29 int id[N*2];   // DFS序
 30 int cou;
 31 
 32 int tot;
 33 struct tree{
 34     int key,fa,son[2];
 35 }t[N*2];
 36 int L[N],R[N];  // 第i個箱子所對應的左右括號在Splay樹上的序號
 37 
 38 inline void pushup(int x){}
 39 inline void pushdown(int x){}
 40 
 41 inline void rotate(int x,int p){
 42     int y=t[x].fa;
 43     pushdown(y);
 44     pushdown(x);
 45 
 46     t[y].son[!p]=t[x].son[p];
 47     t[t[x].son[p]].fa=y;
 48     t[x].fa=t[y].fa;
 49     if (t[x].fa)
 50         t[t[x].fa].son[t[t[x].fa].son[1]==y]=x;
 51     t[x].son[p]=y;
 52     t[y].fa=x;
 53     pushup(y);
 54     pushup(x);
 55 }
 56 
 57 inline void Splay(int x,int to){
 58     while (t[x].fa!=to){
 59         if (t[t[x].fa].fa==to)
 60             rotate(x,t[t[x].fa].son[0]==x);
 61         else {
 62             int y=t[x].fa, z=t[y].fa;
 63             int p=(t[z].son[0]==y);
 64             if (t[y].son[p]==x) 
 65                 rotate(x,!p),rotate(x,p);
 66             else
 67                 rotate(y,p),rotate(x,p);
 68         }
 69     }
 70 }
 71 
 72 inline int newnode(int key,int fa){
 73     int x=tot++;
 74     t[x].key=key;
 75     t[x].fa=fa;
 76     t[x].son[0]=t[x].son[1]=0;
 77 
 78     if (key>0) L[key]=x;
 79     else R[-key]=x;
 80 
 81     return x;
 82 }
 83 
 84 inline int get_min(int x){
 85     while (t[x].son[0]!=0)
 86         x=t[x].son[0];
 87     return x;
 88 }
 89 
 90 inline int get_max(int x){
 91     while (t[x].son[1]!=0) 
 92         x=t[x].son[1];
 93     return x;
 94 }
 95 
 96 inline int bulid(int l,int r,int fa){
 97     if (l>r) return 0;
 98     int x,mid=(l+r)>>1;
 99     x=newnode(id[mid],fa);
100     t[x].son[0]=bulid(l,mid-1,x);
101     t[x].son[1]=bulid(mid+1,r,x);
102     pushup(x);
103     return x;
104 }
105 
106 inline void dfs(int u){    
107     id[cou++]=u;
108     for (int i=head[u];~i;i=e[i].nex)
109         dfs(e[i].to);
110     id[cou++]=-u;
111 }
112 
113 inline void init(){
114     memset(head,-1,sizeof(head));
115     cnt=0;
116     cou=0;
117     tot=1;
118 }
119 
120 inline int query(int a){
121     int x=L[a];
122     Splay(x,0);
123     x=get_min(x);
124     return t[x].key;
125 }
126 
127 inline void move(int a,int b){
128     if (a==b) return;
129 
130     int x=L[a],y=R[a];
131     Splay(x,0);
132     Splay(y,x);
133 
134     int xx=t[x].son[0],yy=t[y].son[1],z=0;
135     z=get_max(xx);
136 
137     t[x].son[0]=0; t[y].son[1]=0;
138     t[xx].fa=0; t[yy].fa=0;
139     if (z!=0) t[z].son[1]=yy;
140     t[yy].fa=z;
141 
142     if (b==0) return;
143 
144     if (query(b)==a){
145         t[x].son[0]=xx; t[y].son[1]=yy;
146         t[xx].fa=x; t[yy].fa=y;
147         t[z].son[1]=0;
148         return;
149     }
150 
151     int l=L[b],r;
152     Splay(l,0);
153     r=get_min(t[l].son[1]);
154     Splay(r,l);
155     t[r].son[0]=x;
156     t[x].fa=r;
157 }
158 
159 int main(){
160     int n,q;
161     int x,y;
162     char ch[10];
163     bool f=false;
164     while (scanf("%d",&n)!=EOF){
165         if (f) puts("");
166         else f=true;
167 
168         init();
169         
170         for (int i=1;i<=n;i++){
171             scanf("%d",&x);
172             addedge(x,i);
173         }
174 
175         dfs(0);
176         int k=0,st=1;
177         for (int i=1;i<=2*n;i++){
178             if (id[i]>0) k++;
179             else k--;
180             if (k==0) {
181                 bulid(st,i,0);
182                 st=i+1;
183             }
184         }
185 
186         scanf("%d",&q);
187         while (q--){
188             scanf("%s",ch);
189             if (ch[0]=='Q') {
190                 scanf("%d",&x);
191                 printf("%d\n",query(x));
192             }
193             else {
194                 scanf("%d %d",&x,&y);
195                 move(x,y);
196             }
197         }
198     }
199 
200     return 0;
201 }
相關文章
相關標籤/搜索