BZOJ 2843 LCT

    这还是道LCT的题,跟着czl做了好多LCT的题啊!没事,czl带我飞!加油,不错,挺顺利的。加油!1592毫秒, 第一次考虑了代码量, 我写这个花了 2800的代码长度, 然而czl只有1900, 代码简化还是很重要啊!

  1 #include<cstdio>
  2 #include<iostream>
  3 #define lc c[k][0]
  4 #define rc c[k][1]
  5 #define rep(i,j,k) for(int i = j; i <= k; i++)
  6 #define maxn 30233
  7 using namespace std;
  8 
  9 int c[maxn][2], pa[maxn], w[maxn], sum[maxn]; 
 10 bool rev[maxn];
 11 int read()
 12 {
 13     int s = 0,t = 1; char c = getchar();
 14     while( !isdigit(c) ){
 15         if( c == '-' ) t = -1; c = getchar();
 16     }
 17     while( isdigit(c) ){
 18         s=  s * 10+ c - '0'; c = getchar();
 19     }
 20     return s * t;
 21 }
 22 
 23 bool root(int x)
 24 {
 25     int k = pa[x];
 26     return lc != x && rc != x;
 27 }
 28 
 29 void maintain(int k)
 30 {
 31     sum[k] = sum[lc] + sum[rc] + w[k];
 32 }
 33 
 34 void rorate(int k)
 35 {
 36     int fa = pa[k], gfa = pa[fa];
 37     int l = c[fa][1] == k, r = l ^ 1;
 38     if( !root(fa) ){
 39         c[gfa][c[gfa][1] == fa] = k;
 40     }
 41     pa[fa] = k, pa[k] = gfa, pa[c[k][r]] = fa;
 42     c[fa][l] = c[k][r], c[k][r] = fa; maintain(fa), maintain(k); 
 43 }
 44 
 45 void pushdown(int k)
 46 {
 47     if( rev[k] ){
 48         rev[k] ^= 1, rev[lc] ^= 1, rev[rc] ^= 1;
 49         swap(lc,rc);
 50     }
 51 }
 52 
 53 int q[maxn];
 54 void splay(int k)
 55 {
 56     int top = 0; q[++top] = k;
 57     for(int x = k; !root(x); x = pa[x] )
 58        q[++top] = pa[x];
 59     while( top ) pushdown(q[top--]);
 60     while( !root(k) ){
 61         int fa = pa[k], gfa = pa[fa];
 62         if( !root(fa) ){
 63             if( c[gfa][1] == fa ^ c[fa][1] == k ) rorate(k);
 64             else rorate(fa);
 65         }
 66         rorate(k);
 67     }
 68 }
 69 
 70 void access(int k)
 71 {
 72     for(int t = 0; k; t = k, k = pa[k])
 73        splay(k), rc = t, maintain(k);
 74 }
 75 
 76 void makeroot(int k)
 77 {
 78     access(k), splay(k), rev[k] ^= 1;
 79 }
 80 
 81 void link(int x,int y)
 82 {
 83     makeroot(x), pa[x] = y;
 84 }
 85 
 86 void split(int x,int y)
 87 {
 88     makeroot(x), access(y), splay(y); c[y][0] = pa[x] = 0;
 89     maintain(y);
 90 }
 91 
 92 int find(int k)
 93 {
 94     access(k), splay(k);
 95     while( lc ) k = lc;
 96     return k;
 97 }
 98 
 99 int query(int x,int y)
100 {
101     makeroot(x), access(y), splay(y); return sum[y];
102 }
103 
104 int main()
105 {
106     int n = read();
107     rep(i,1,n) w[i] = read(); char  c[20];
108     int m = read();
109     rep(i,1,m){
110         scanf("%s", c);
111         if( c[0] == 'b' ) {
112             int x = read(), y = read();
113             int kx = find(x), ky = find(y);
114             if( kx != ky ) {
115                 puts("yes");
116                 link(x,y);
117             }
118             else puts("no");
119         }
120         if( c[0] == 'e' ){
121             int x = read(), y = read();
122             int kx = find(x), ky = find(y);
123             if( kx != ky ) puts("impossible");
124             else printf("%d
", query(x,y));
125         }
126         if( c[0] == 'p' ){
127             int x = read(), y = read();
128             splay(x); w[x] = y; maintain(x);
129         }
130     }
131     return 0;
132 }
原文地址:https://www.cnblogs.com/83131yyl/p/5116508.html