首页 > 其他 > 详细

Luogu 3690 LCT - 模板

时间:2018-09-20 20:49:01      阅读:203      评论:0      收藏:0      [点我收藏+]

推荐几篇比较好的博客:

 

FlashHu 的 讲解比较好 : 传送门

Candy 的 代码~ : 传送门

以及神犇Angel_Kitty的 学习笔记: 传送门

 

Code

技术分享图片
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define rd read()
  5 using namespace std;
  6 
  7 const int N = 1e5 + 5;
  8 int n, m;
  9 
 10 int read() {
 11     int X = 0, p = 1; char c =getchar();
 12     for (; c > 9 || c < 0; c = getchar()) 
 13         if (c == -) p = -1;
 14     for (; c >= 0 && c <= 9; c = getchar()) 
 15         X = X * 10 + c - 0;
 16     return X * p;
 17 }
 18 
 19 namespace LCT {
 20     int f[N], ch[N][2], rev[N], val[N], sum[N];
 21 
 22 #define lc(x) ch[x][0]
 23 #define rc(x) ch[x][1]
 24 
 25     int isroot(int x) {
 26         return ch[f[x]][0] != x && ch[f[x]][1] != x;
 27     }
 28 
 29     int get(int x) {
 30         return ch[f[x]][1] == x;
 31     }
 32 
 33     void up(int x) {
 34         sum[x] = sum[lc(x)] ^ sum[rc(x)] ^ val[x];
 35     }
 36 
 37     void rerv(int x) {
 38         swap(rc(x), lc(x));
 39         rev[x] ^= 1;
 40     }
 41 
 42     void pushdown(int x) {
 43         if (rev[x]) {
 44             if (lc(x)) rerv(lc(x)); 
 45             if (rc(x)) rerv(rc(x));
 46             rev[x] = 0;
 47         }
 48     }
 49 
 50     void pd(int x) {
 51         if (!isroot(x))
 52             pd(f[x]);
 53         pushdown(x);
 54     }
 55 
 56     void rotate(int x) {
 57         int old = f[x], oldf = f[old], son = ch[x][get(x) ^ 1];
 58         if (!isroot(old)) ch[oldf][get(old)] = x;
 59         ch[x][get(x) ^ 1] = old;
 60         ch[old][get(x)] = son;
 61         f[x] = oldf; f[old] = x; f[son] = old;
 62         up(old); up(x);
 63     }
 64 
 65     void splay(int x) {
 66         pd(x);
 67         for (; !isroot(x); rotate(x)) 
 68             if (!isroot(f[x]))
 69                 rotate(get(x) == get(f[x]) ? f[x] : x);
 70     }
 71 
 72     void access(int x) {
 73         for (int y = 0; x; y = x, x = f[x])
 74             splay(x), rc(x) = y, up(x);
 75     }
 76 
 77     void mroot(int x) {
 78         access(x); splay(x); rerv(x);
 79     }
 80     
 81     int findr(int x) {
 82         access(x); splay(x);
 83         while (lc(x)) {
 84             pushdown(x);
 85             x = lc(x);
 86         }
 87         return x;
 88     }
 89 
 90     void link(int x, int y) {
 91         mroot(x);
 92         if (findr(y) == x)
 93             return;
 94         f[x] = y;
 95     }
 96 
 97     void cut(int x, int y) {
 98         mroot(x);
 99         if(findr(y) != x || f[x] != y || ch[x][1])
100             return;
101         f[x] = ch[y][0] = 0;
102         up(y);
103     }
104 }
105 using namespace LCT;
106 
107 int main()
108 {
109     n = rd; m = rd;
110     for (int i = 1; i <= n; ++i)
111         val[i] = rd;
112     for (int i = 1; i <= m; ++i) {
113         int k, u, v;
114         k = rd;
115         if (k == 0) {
116             u = rd; v = rd;
117             mroot(u); access(v); splay(v);
118             printf("%d\n", sum[v]);
119         }
120         if (k == 1) {
121             u = rd, v = rd;
122             link(u, v);
123         }
124         if (k == 2) {
125             u = rd; v = rd;
126             cut(u, v);
127         }
128         if (k == 3) {
129             u = rd; v = rd;
130             val[u] = v;
131             up(u); splay(u);
132         }
133     }
134 }
View Code

 

Luogu 3690 LCT - 模板

原文:https://www.cnblogs.com/cychester/p/9683108.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!