HDU 2475 Box

Box

Time Limit: 5000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 2475
64-bit integer IO format: %I64d      Java class name: Main
There are N boxes on the ground, which are labeled by numbers from 1 to N. The boxes are magical, the size of each one can be enlarged or reduced arbitrarily.
Jack can perform the “MOVE x y” operation to the boxes: take out box x; if y = 0, put it on the ground; Otherwise, put it inside box y. All the boxes inside box x remain the same. It is possible that an operation is illegal, that is, if box y is contained (directly or indirectly) by box x, or if y is equal to x.
In the following picture, box 2 and 4 are directly inside box 6, box 3 is directly inside box 4, box 5 is directly inside box 1, box 1 and 6 are on the ground.

The picture below shows the state after Jack performs “MOVE 4 1”:

Then he performs “MOVE 3 0”, the state becomes:

During a sequence of MOVE operations, Jack wants to know the root box of a specified box. The root box of box x is defined as the most outside box which contains box x. In the last picture, the root box of box 5 is box 1, and box 3’s root box is itself.
 

Input

Input contains several test cases.
For each test case, the first line has an integer N (1 <= N <= 50000), representing the number of boxes.
Next line has N integers: a1, a2, a3, ... , aN (0 <= ai <= N), describing the initial state of the boxes. If ai is 0, box i is on the ground, it is not contained by any box; Otherwise, box i is directly inside box ai. It is guaranteed that the input state is always correct (No loop exists).
Next line has an integer M (1 <= M <= 100000), representing the number of MOVE operations and queries.
On the next M lines, each line contains a MOVE operation or a query:
1.  MOVE x y, 1 <= x <= N, 0 <= y <= N, which is described above. If an operation is illegal, just ignore it.
2.  QUERY x, 1 <= x <= N, output the root box of box x.
 

Output

For each query, output the result on a single line. Use a blank line to separate each test case.
 

Sample Input

2
0 1
5
QUERY 1
QUERY 2
MOVE 2 0
MOVE 1 2
QUERY 1
6
0 6 4 6 1 0
4
MOVE 4 1
QUERY 3
MOVE 1 4
QUERY 1

Sample Output

1
1
2

1
1

Source

 
解题:Link-Cut tree
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 300010;
  4 struct LCT{
  5     int fa[maxn],ch[maxn][2],parent[maxn];
  6     void init(){
  7         memset(fa,0,sizeof fa);
  8         memset(ch,0,sizeof ch);
  9     }
 10     void rotate(int x,int kd){
 11         int y = fa[x];
 12         ch[y][kd^1] = ch[x][kd];
 13         fa[ch[x][kd]] = y;
 14         fa[x] = fa[y];
 15         ch[x][kd] = y;
 16         fa[y] = x;
 17         if(fa[x]) ch[fa[x]][y == ch[fa[x]][1]] = x;
 18     }
 19     void splay(int x,int goal = 0){
 20         int y = x;
 21         while(fa[y]) y = fa[y];
 22         if(x != y){
 23             parent[x] = parent[y];
 24             parent[y] = 0;
 25             while(fa[x] != goal){
 26                 if(fa[fa[x]] == goal) rotate(x,x == ch[fa[x]][0]);
 27                 else{
 28                     int y = fa[x],z = fa[y],s = (y == ch[z][0]);
 29                     if(x == ch[y][s]){
 30                         rotate(x,s^1);
 31                         rotate(x,s);
 32                     }else{
 33                         rotate(y,s);
 34                         rotate(x,s);
 35                     }
 36                 }
 37             }
 38         }
 39     }
 40     void access(int x){
 41         for(int y = 0; x; x = parent[x]){
 42             splay(x);
 43             fa[ch[x][1]] = 0;
 44             parent[ch[x][1]] = x;
 45             ch[x][1] = y;
 46             fa[y] = x;
 47             parent[y] = 0;
 48             y = x;
 49         }
 50     }
 51     int GetRoot(int x){
 52         access(x);
 53         splay(x);
 54         while(ch[x][0]) x = ch[x][0];
 55         return x;
 56     }
 57     void cut(int x){
 58         access(x);
 59         splay(x);
 60         parent[ch[x][0]] = parent[x];
 61         parent[x] = 0;
 62         fa[ch[x][0]] = 0;
 63         ch[x][0] = 0;
 64     }
 65     void join(int x,int y){
 66         if(!y) cut(x);
 67         else{
 68             access(y);
 69             splay(y);
 70             int z = x;
 71             while(fa[z]) z = fa[z];
 72             if(z != y){
 73                 cut(x);
 74                 parent[x] = y;
 75             }
 76         }
 77     }
 78 }lct;
 79 int main(){
 80     int n,m,u,v;
 81     char op[10];
 82     bool flag = false;
 83     while(~scanf("%d",&n)){
 84         lct.init();
 85         if(flag) putchar('\n');
 86         for(int i = 1; i <= n; ++i)
 87             scanf("%d",&lct.parent[i]);
 88         scanf("%d",&m);
 89         while(m--){
 90             scanf("%s%d",op,&u);
 91             if(op[0] == 'Q') printf("%d\n",lct.GetRoot(u));
 92             else{
 93                 scanf("%d",&v);
 94                 lct.join(u,v);
 95             }
 96         }
 97         flag = true;
 98     }
 99     return 0;
100 }
View Code

 

posted @ 2015-10-16 13:37  狂徒归来  阅读(310)  评论(0编辑  收藏  举报