bzoj 3282
回顾一下LCT,容易写错的地方:
1、每次断掉Splay中的边,必须update一下父亲节点,再根据具体情况是否splay父亲节点。
2、养成没有用的值(比如当pre[u]不为0时的pnt[u])不去乱修改的习惯。
1 /************************************************************** 2 Problem: 3282 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:2968 ms 7 Memory:10712 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <utility> 12 #include <set> 13 #define N 300010 14 using namespace std; 15 16 typedef pair<int,int> dpr; 17 18 struct Lct { 19 int pnt[N], pre[N], son[N][2], val[N], xsum[N], rtg[N]; 20 21 void update( int nd ) { 22 xsum[nd] = val[nd]; 23 if( son[nd][0] ) xsum[nd] ^= xsum[son[nd][0]]; 24 if( son[nd][1] ) xsum[nd] ^= xsum[son[nd][1]]; 25 } 26 void rotate( int nd, int d ) { 27 int p=pre[nd]; 28 int s=son[nd][!d]; 29 int ss=son[s][d]; 30 31 son[nd][!d] = ss; 32 son[s][d] = nd; 33 if( p ) son[p][ nd==son[p][1] ] = s; 34 else { 35 pnt[s]=pnt[nd]; 36 pnt[nd] = 0; 37 } 38 39 pre[nd] = s; 40 pre[s] = p; 41 if( ss ) pre[ss] = nd; 42 43 update( nd ); 44 update( s ); 45 } 46 void pushdown( int nd ) { 47 if( rtg[nd] ) { 48 int &ls=son[nd][0], &rs=son[nd][1]; 49 swap(ls,rs); 50 if( ls ) rtg[ls] ^= 1; 51 if( rs ) rtg[rs] ^= 1; 52 rtg[nd] = 0; 53 } 54 } 55 void big_push( int nd ) { 56 if( pre[nd] ) big_push(pre[nd]); 57 pushdown(nd); 58 } 59 void splay( int nd, int top=0 ) { 60 big_push( nd ); 61 while( pre[nd]!=top ) { 62 int p=pre[nd]; 63 int nl=nd==son[p][0]; 64 if( pre[p]==top ) { 65 rotate( p, nl ); 66 } else { 67 int pp=pre[p]; 68 int pl=p==son[pp][0]; 69 if( nl==pl ) { 70 rotate( pp, pl ); 71 rotate( p, nl ); 72 } else { 73 rotate( p, nl ); 74 rotate( pp, pl ); 75 } 76 } 77 } 78 } 79 void access( int nd ) { 80 int u=nd; 81 int v=0; 82 while( u ) { 83 splay(u); 84 int s=son[u][1]; 85 if( s ) { 86 pre[s] = 0; 87 pnt[s] = u; 88 } 89 if( v ) { 90 pre[v] = u; 91 pnt[v] = 0; 92 } 93 son[u][1] = v; 94 update(u); 95 v = u; 96 u = pnt[u]; 97 } 98 splay(nd); 99 } 100 int findroot( int u ) { 101 while( pre[u] ) u=pre[u]; 102 while( pnt[u] ) { 103 u=pnt[u]; 104 while( pre[u] ) u=pre[u]; 105 } 106 return u; 107 } 108 void makeroot( int u ) { 109 access(u); 110 rtg[u] ^= 1; 111 } 112 void cut( int u, int v ) { 113 makeroot(u); 114 access(v); 115 pnt[u] = pre[u] = 0; 116 son[v][0] = 0; 117 update(v); 118 } 119 void link( int u, int v ) { 120 makeroot(u); 121 makeroot(v); 122 pnt[u] = v; 123 } 124 int query( int u, int v ) { 125 makeroot(u); 126 access(v); 127 return xsum[v]; 128 } 129 void modify( int u, int v ) { 130 access(u); 131 xsum[u] ^= val[u]; 132 val[u] = v; 133 xsum[u] ^= val[u]; 134 } 135 }T; 136 137 int n, m; 138 set<dpr> st; 139 140 int main() { 141 scanf( "%d%d", &n, &m ); 142 for( int i=1,w; i<=n; i++ ) { 143 scanf( "%d", &w ); 144 T.modify( i, w ); 145 } 146 for( int i=1,opt,u,v; i<=m; i++ ) { 147 scanf( "%d%d%d", &opt, &u, &v ); 148 if( opt==0 ) { 149 printf( "%d\n", T.query(u,v) ); 150 } else if( opt==1 ) { 151 if( u>v ) swap(u,v); 152 if( T.findroot(u)!=T.findroot(v) ) { 153 st.insert( dpr(u,v) ); 154 T.link(u,v); 155 } 156 } else if( opt==2 ) { 157 if( u>v ) swap(u,v); 158 if( st.count( dpr(u,v) ) ) { 159 st.erase( dpr(u,v) ); 160 T.cut(u,v); 161 } 162 } else { 163 T.modify( u, v ); 164 } 165 } 166 }