Bzoj_3282_tree_ (LCT)

Source: Internet
Author: User

Describe

http://www.lydsy.com/JudgeOnline/problem.php?id=3282

Given n points and weights, four operations:

0. Ask for the XOR of the point weights on the x, y path.

1. Connect x, Y.

2. Disconnect x, Y.

3. Change the weight of X to T.

Analysis

LCT template questions.

Say a few points of your own perception and need to pay attention to the place (the original tree is called a tree, the balance tree is called splay to avoid confusion):

1.LCT is used splay to maintain a forest (by splitting the chain), splay to the depth of the keyword, that is, the depth of the small on the left, the depth of the large on the right. Each tree in the forest has one or more splay, and at the beginning each point is an independent splay. If two dots x, Y are connected , assuming X's depth is small, we set Y->PA to X, but note that X's child is not set to Y. Such a tree, or each point is a separate splay, but unlike ordinary splay, where the root of the splay is not necessarily connected to null, But its father node is not attached to it.

The 2.Access operation is the most basic and the most important operation of LCT, and its function is: if we access (x), then the root node of x is located in the path of the x in a splay. So if you make multiple access, A tree is divided into many splay and each splay may no longer represent just one point (you can draw your own picture). For splay root node, its PA represents the ancestor of this splay (is a chain) tree, and for non-splay nodes, Its father is the father of it in the splay. So we have a way to judge the splay root node: see if its PA is attached to it, if connected, then this point is not the root of splay, if not connected, then this point is the root of splay. Of course, The root node of the tree is the point where the father is null.

Also note that access (x) must be followed by splay (x), (the original X). For the following reasons (do not understand the first jump over to see below):

(1). In Access operation, each time the depth of the splay chain on the tree is hung on the depth of the point, are hanging on the right child, but none of the push_up () operation, so after a splay (x), x along the right side of the process will be all not push_ The up point is push_up. (You can also push_up () at every step of the access function, but it seems to be a bit slower)

(2). Ensure that x is also the root of splay after Make_root (x), so that the link function make_root (x) can be x->pa=y directly.

(3). Access (x), regardless of the operation of the X is splay first to a point in the splay splay operation, X point at the root node of splay, because there is a fix function, so the x position of the tag will be passed. If we make_root (x) After that, this ensures that X is the leftmost, which is the least depth, so that the Find_root function can find the root of the correct tree.

3.make_root operation. After Make_root (x), x is the root of the tree (there is no such action to the tree). We think we'll find that for the tree's original root y and now the X to become the root, we just need to invert the depth of all points on the Y-x path. So we access ( x), splay (x), x->rev^=true (reverses the depth of all points in the splay of the chain representing y to x).

4.link operation. Make_root (x), and then directly connected (Make_root in the splay after access, so x must be the root of the splay, so it can be directly connected).

5.cut operation. Make_root (x), Access (y), splay (y) so that this splay has only X, Y, two points, and X. y is the left son, then X->pa=null,y->ch[0]=null.

The importance of the 6.fix function. The general splay can be transferred to the Mark (Rev) while the splay is in operation. But the splay in LCT is always changing, maybe after a while the splay is no longer the original point (more new, less some of the previous). If we turn to the side of the flag, it will lead to splay in the above mark is not completely passed down, a bit if the following point is changed (the original point is not, add another point), the mark will be a problem. So we splay to find the root of splay and then from top to bottom ( Until the point x of the splay operation is to be performed, put all the marks down so that all the tags that affect the x's child nodes are cleared. Because every time splay change point is the first splay (x), then x->ch[1] replaced, so we each splay (x) When the mark that will affect the X child node is processed, and then the child node of X, there will be no problem.

7. Since access must be splay, I'll write splay directly into the access function.

8. In fact, I think I am not clear about the point ...

1#include <bits/stdc++.h>2 using namespacestd;3 4 Const intmaxn=300000+5;5 intn,m;6 structnode{7     intV,s;BOOLRev;8node* ch[2],*PA;9Nodeintv,node* t): V (v), s (0), Rev (false) {ch[0]=ch[1]=pa=t;}Ten     BOOLD () {returnpa->ch[1]== This; } One     BOOLC () {returnpa->ch[0]== This|| pa->ch[1]== This; }//judge whether this point has been attached to the father. A     voidSETC (node* T,BOOLd) {ch[d]=t; t->pa= This; } -     voidPush_up () {s=ch[0]->s^ch[1]->s^v;} -     voidPush_down () { the         if(rev) { -ch[0]->rev^=true; -ch[1]->rev^=true; -Swap (ch[0],ch[1]); +rev=false; -         } +     } A}* t[maxn],*NULL; at voidRot (node*o) { -node* pa=o->pa;BOOLD=o->d (); -Pa->push_down (); O->Push_down (); -     if(Pa->c ()) pa->pa->setc (o,pa->d ()); -     ElseO->pa=pa->PA; -PA-&GT;SETC (o->ch[!d],d); inO-&GT;SETC (pa,!d); -Pa->push_up (); to } + voidFix (node*o) { -     if(O->c ()) Fix (o->PA); theO->Push_down (); * } $ voidSplay (node*o) {Panax NotoginsengFix (O);//You must find the root and then put the mark, otherwise the tag is not completely decentralized, splay is dynamic, error. -      while(o->C ()) the         if(!o->pa->c ()) Rot (o); +         ElseO->d () ==o->pa->d ()? (Rot (o->PA), Rot (o)):(rot (o), Rot (o)); AO->push_up (); the } + voidAccess (node* x) {//after access, be sure to splay the original X -Node *y=NULL; $      for(; x!=NULL; Y=x, x=x->PA) { $ splay (x); -x->ch[1]=y; -     } the } - voidMake_root (node*o) {Wuyi access (o); the splay (o); -o->rev^=true; Wu } - voidLink (Node *u,node *v) { About make_root (u); $U->pa=v; - } - voidCut (node* U,node *v) { - make_root (u); A access (v); + splay (v); theU->pa=NULL; -v->ch[0]=NULL; $ } thenode* Find_root (node*o) { the access (o); the splay (o); the      while(o->ch[0]!=NULL) o=o->ch[0]; -     returno; in } the intQuery (Node *u,node *v) { the make_root (u); About access (v); the splay (v); the     returnV->s; the } + voidChange (node *x,inty) { -x->v=y; theX->push_up ();Bayi } the intMain () { the     NULL=NewNode0, NULL); -scanf"%d%d",&n,&m); -      for(intI=1; i<=n;i++){ the         intX scanf"%d",&x); thet[i]=NewNode (x,NULL); the     } the      for(intI=1; i<=m;i++){ -         intc,x,y; thescanf"%d%d%d",&c,&x,&y); the         if(c==0) printf ("%d\n", Query (T[x],t[y])); the         Else if(c==1){if(Find_root (t[x])! =Find_root (T[y]) Link (t[x],t[y]); }94         Else if(c==2){if(Find_root (t[x]) = =Find_root (T[y]) cut (t[x],t[y]); } the         Else if(c==3) Change (t[x],y); the     } the     return 0;98}
View Code

3282:treetime limit:30 Sec Memory limit:512 MB
submit:1417 solved:615
[Submit] [Status] [Discuss] Description

Given the n points and the weights for each point, you need to handle the next m operation. There are 4 types of operations. The operation is numbered from 0 to 3. Points are numbered from 1 to N.

0: followed by two integers (x, y), which represents the XOR and of the weights of the points that are queried on the path from X to Y. Ensure that x to Y is unicom.

1: followed by two integers (x, y), representing the connection x to Y, if x to Y is connected, there is no need to connect.

2: followed by two integers (x, y), representing the delete edge (x, y), does not guarantee that the edge (x, y) exists.

3: followed by two integers (x, y) to change the weight on point x to Y.

Input

The 1th line is two integers, N and M, respectively, representing the number of points and operands.

Line 2nd to line n+1, one integer per line, integer within [1,10^9], representing the weight of each point.

Row n+2 to line n+m+1, three integers per line, representing the type of operation and the amount of action required.

Output

For each operation number No. 0, you must output the XOR of the point right on the path x to Y and.

Sample INPUT3 3
1
2
3
1 1 2
0 1 2
0 1 1
Sample OUTPUT3
1
HINT

1<=n,m<=300000

Source

Dynamic tree

Bzoj_3282_tree_ (LCT)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.