Box Time limit:10000/5000 MS (java/others) Memory limit:32768/32768 K (java/others)
Total submission (s): 2421 Accepted Submission (s): 737
Problem Description There is N boxes on the ground, which is labeled by numbers from 1 to N. The boxes is 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 a operation is illegal, which is, if Box y are contained (directly or indirectly) by box X, or if Y is possible 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 is on the ground.
The picture below shows, 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. 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 had 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 was on the ground, it's not contained by any box; Otherwise, Box I is directly inside box AI. It is guaranteed, the input state was always correct (No loop exists).
Next line have 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 of the 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-Asia Regional Chengdu
Implementation of partial operation using splay stretching tree +lct
Because you cannot change the root, leave only the access operation.
Method:
1. Query the root of the point V, direct access, and then find the Father
2. For changing the subtree to another node, record each subtree of the father, Access (Fa[u]) so you are separated from the father,
Then the father of U is empty, so you can take the tree of U.
To judge the legality, you just need to determine if V is the father is u can.
The legal father of U is V
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <
Vector> using namespace std;
#define MAXN 200007 #define INF 1000000000 #define LL int struct node{Node *fa,*ch[2];
BOOL Root;
int id;
};
Node POOL[MAXN];
Node *NIL,*TREE[MAXN];
int cnt = 0;
void init () {cnt = 1;
Nil = tree[0] = pool;
Nil->ch[0] = nil->ch[1] = nil;
Nil->root = true;
Nil->fa = nil;
Nil->id = 0;
} Node *newnode (int id,node *f) {pool[cnt].fa = f;
Pool[cnt].ch[0]=pool[cnt].ch[1]=nil;
Pool[cnt].id = ID;
Pool[cnt].root = true;
Return &pool[cnt++];
}//The node x is rotated to the position of the father in splay ****** void rotate (node *x) {node *f = x->fa, *ff = f->fa;
int t = (f->ch[1] = = x);
if (f->root) X->root = True, F->root = false;
else ff->ch[ff->ch[1] = = f] = x;
X->FA = FF;
F->ch[t] = x->ch[t^1];
X->CH[T^1]->FA = f;
X->ch[t^1] = f; F-&gT;FA = x;
}//The node x is rotated to the root of the splay where x is located ****** void splay (node *x) {node *f, *ff;
while (!x->root) {f = X->fa,ff = f->fa;
if (!f->root) if ((ff->ch[1]==f) && (f->ch[1] = = x)) rotate (f);
else rotate (x);
Rotate (x);
}}//Take x to the root of the path and form a path****** node *access (node *x) {node *y = nil;
while (x! = nil) {splay (x);
X->ch[1]->root = true;
(x->ch[1] = y)->root = false;
y = x;
x = x->fa;
} return y;
} Char word[30];
node* Findroot (node*x) {if (x->ch[0] = = nil) return x;
Return Findroot (x->ch[0]);
} NODE*FA[MAXN];
int main () {int n,q,u,v,tt=0;
Node*x;
while (scanf ("%d", &n)!=eof) {if (TT) puts ("");
tt++;
Init ();
for (int i = 1;i <= n; i++) {Tree[i] = NewNode (I,nil);
} for (int i = 1;i <= n; i++) {scanf ("%d", &u);
TREE[I]->FA = Tree[u]; Fa[i] = Tree[u];
} scanf ("%d", &q);
while (q--) {scanf ("%s", word);
if (word[0] = = ' Q ') {scanf ("%d", &u);
x = Access (Tree[u]);
x = Findroot (x);
printf ("%d\n", x->id);
Splay (x);
} else {scanf ("%d%d", &u,&v);
Access (Fa[u]);
Splay (Tree[u]);
Tree[u]->fa = nil;
x = Access (Tree[v]);
if (findroot (x) = = Tree[u]) {splay (tree[u]);
TREE[U]->FA = Fa[u];
} else {tree[u]->fa = Tree[v];
Fa[u] = Tree[v];
}}}} return 0;
}/* 2 0 1 Query 1 query 2 Move 2 0 Move 1 2 QUERY 1 */