1A爽,感觉又对指针重怀信心了呢= =,模板题,注意单点修改时splay就好,其实按吾本意是没写的也A了,不过应该加上能更好维护平衡性。
。。还是得加上好= =
1 #include <iostream> 2 #include <cstdio> 3 #define N 300010 4 using namespace std; 5 int n,m; 6 struct node 7 { 8 node *fa,*ch[2]; 9 int xor_sum,data; 10 bool rev; 11 node(int x); 12 bool chr() {return this==fa->ch[1];} 13 bool isrt() {return this!=fa->ch[1] && this!=fa->ch[0];} 14 void setc(node *x,int t) {this->ch[t]=x; x->fa=this;} 15 void push_up() {xor_sum=ch[0]->xor_sum^ch[1]->xor_sum^data;} 16 void push_down() 17 { 18 if (!isrt()) fa->push_down(); 19 if (rev) 20 { 21 ch[1]->rev^=1; 22 ch[0]->rev^=1; 23 swap(ch[0],ch[1]); 24 rev=0; 25 } 26 } 27 }*null=new node(0),*lct[N]; 28 node::node(int x) 29 { 30 fa=ch[1]=ch[0]=null; 31 data=xor_sum=x; 32 rev=0; 33 } 34 inline int read() 35 { 36 int ans=0,f=1; 37 char c; 38 while (!isdigit(c=getchar())){if (c=='-') f=-1;} 39 ans=c-'0'; 40 while (isdigit(c=getchar())) ans=ans*10+c-'0'; 41 return ans*f; 42 } 43 namespace LCT 44 { 45 void rotate(node *x) 46 { 47 node *r=x->fa; 48 int t=x->chr(); 49 if (x==null || r==null) return; 50 //x->push(); y->push(); 51 if (r->isrt()) x->fa=r->fa; 52 else r->fa->setc(x,r->chr()); 53 r->setc(x->ch[t^1],t); 54 x->setc(r,!t); 55 x->push_up(); r->push_up(); 56 } 57 void splay(node *x) 58 { 59 x->push_down(); 60 for (;!x->isrt();rotate(x)) 61 if (!x->fa->isrt()) 62 if (x->chr()==x->fa->chr()) rotate(x->fa); 63 else rotate(x); 64 x->push_up(); 65 } 66 void Access(node *x) 67 { 68 node *y=null; 69 for (;x!=null;y=x,x=x->fa) 70 { 71 splay(x); 72 x->ch[1]=y; 73 } 74 } 75 void MakeRoot(node *x) 76 { 77 Access(x); splay(x); x->rev^=1; 78 } 79 void Link(node *x,node *y) 80 { 81 MakeRoot(x); //Access(y); splay(y); 82 x->fa=y; 83 } 84 void Cut(node *x,node *y) 85 { 86 MakeRoot(x); Access(y); splay(y); 87 y->ch[0]->fa=null; y->ch[0]=null; 88 } 89 node *Findfa(node *x) 90 { 91 Access(x); splay(x); 92 while (x->ch[0]!=null) x=x->ch[0]; 93 return x; 94 } 95 void Change(node *x,int v) 96 { 97 x->push_down(); 98 splay(x); 99 x->data=v; 100 x->push_up(); 101 } 102 int Query(node *x,node *y) 103 { 104 MakeRoot(x); 105 Access(y); 106 splay(y); 107 return y->xor_sum; 108 } 109 } 110 using namespace LCT; 111 int main() 112 { 113 int temp,x,y; 114 n=read(); 115 m=read(); 116 for (int i=1;i<=n;i++) x=read(),lct[i]=new node(x); 117 for (int i=1;i<=m;i++) 118 { 119 temp=read(); x=read(); y=read(); 120 switch (temp) 121 { 122 case 0:printf("%d ",LCT::Query(lct[x],lct[y])); break; 123 case 1:if (Findfa(lct[x])!=Findfa(lct[y])) Link(lct[x],lct[y]); break; 124 case 2:if (Findfa(lct[x])==Findfa(lct[y])) Cut(lct[x],lct[y]); break; 125 case 3:Change(lct[x],y); break; 126 } 127 } 128 return 0; 129 }
Description
给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。
0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点X上的权值变成Y。
Input
第1行两个整数,分别为N和M,代表点数和操作数。
第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。
第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。
Output
对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。
Sample Input
3 3
1
2
3
1 1 2
0 1 2
0 1 1
1
2
3
1 1 2
0 1 2
0 1 1
Sample Output
3
1
1
HINT
1<=N,M<=300000