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 }
View Code

 

posted @ 2015-04-06 20:53  idy002  阅读(185)  评论(0编辑  收藏  举报