cychester

Luogu 3690 LCT - 模板

推荐几篇比较好的博客:

 

FlashHu 的 讲解比较好 : 传送门

Candy 的 代码~ : 传送门

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

 

Code

V 模板

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define rd read()
  5 #define ll long long
  6 using namespace std;
  7 
  8 const int N = 1e5 + 5;
  9 const int mod = 51061;
 10 
 11 int n, m;
 12 
 13 int read() {
 14     int X = 0, p = 1; char c = getchar();
 15     for (; c > '9' || c < '0'; c = getchar())
 16         if (c == '-') p = -1;
 17     for (; c >= '0' && c <= '9'; c = getchar())
 18         X = X * 10 + c - '0';
 19     return X * p;
 20 }
 21 
 22 namespace LCT {
 23     int ch[N][2], tun[N], f[N], size[N];
 24     ll sum[N], val[N], tim[N], ad[N];
 25 #define lc(x) ch[x][0]
 26 #define rc(x) ch[x][1]
 27     int isroot(int x) {
 28         return lc(f[x]) != x && rc(f[x]) != x;
 29     }
 30 
 31     int get(int x) {
 32         return rc(f[x]) == x;
 33     }
 34 
 35     void up(int x) {
 36         sum[x] = val[x];
 37         size[x] = 1;
 38         if (lc(x)) sum[x] += sum[lc(x)], size[x] += size[lc(x)];
 39         if (rc(x)) sum[x] += sum[rc(x)], size[x] += size[rc(x)];
 40         sum[x] %= mod;
 41     }
 42 
 43     void time(int x, ll d) {
 44         val[x] = val[x] * d % mod;
 45         sum[x] = sum[x] * d % mod;
 46         ad[x] = ad[x] * d % mod;
 47         tim[x] = tim[x] * d % mod;
 48     }
 49 
 50     void add(int x, ll d) {
 51         sum[x] = (sum[x] + d * size[x]) % mod;
 52         val[x] = (val[x] + d) % mod;
 53         ad[x] = (ad[x] + d) % mod;
 54     }
 55 
 56     void rev(int x) {
 57         swap(lc(x), rc(x));
 58         tun[x] ^= 1;
 59     }
 60 
 61     void pushdown(int x) {
 62         if (tim[x] != 1) {
 63             if (lc(x)) time(lc(x), tim[x]);
 64             if (rc(x)) time(rc(x), tim[x]);
 65             tim[x] = 1;
 66         }
 67         if (ad[x]) {
 68             if (lc(x)) add(lc(x), ad[x]);
 69             if (rc(x)) add(rc(x), ad[x]);
 70             ad[x] = 0;
 71         }
 72         if (tun[x]) {
 73             if (lc(x)) rev(lc(x));
 74             if (rc(x)) rev(rc(x));
 75             tun[x] = 0;
 76         }
 77     }
 78 
 79     void pd(int x) {
 80         if (!isroot(x))
 81             pd(f[x]);
 82         pushdown(x);
 83     }
 84 
 85     void rotate(int x) {
 86         int old = f[x], oldf = f[old], son = ch[x][get(x) ^ 1];
 87         if (!isroot(old)) ch[oldf][get(old)] = x;
 88         ch[x][get(x) ^ 1] = old;
 89         ch[old][get(x)] = son;
 90         f[old] = x; f[x] = oldf; f[son] = old;
 91         up(old); up(x);
 92     }
 93 
 94     void splay(int x) {
 95         pd(x);
 96         for (; !isroot(x); rotate(x)) 
 97             if(!isroot(f[x]))
 98                 rotate(get(f[x]) == get(x) ? f[x] : x);
 99     }
100 
101     void access(int x) {
102         for (int y = 0; x; y = x, x = f[x])
103             splay(x), ch[x][1] = y, up(x);
104     }
105 
106     void mroot(int x) {
107         access(x); splay(x); rev(x);
108     }
109 
110     void split(int x, int y) {
111         mroot(x); access(y); splay(y);
112     }
113 
114     void link(int x, int y) {
115         mroot(x);
116         f[x] = y;
117     }
118 
119     void cut(int x, int y) {
120         split(x, y);
121         f[x] = ch[y][0] = 0;
122         up(y);
123     }
124 }
125 using namespace LCT;
126 
127 int main()
128 {
129     n = rd; m = rd;
130     for (int i = 1; i <= n; ++i)
131         size[i] = tim[i] = val[i] = sum[i] = 1;
132     for (int i = 1; i < n; ++i) {
133         int u = rd, v = rd;
134         link(u, v);
135     }
136     for (; m; m--) {
137         char op[5];
138         scanf("%s", op);
139         if (op[0] == '+') {
140             int u = rd, v = rd, d = rd;
141             split(u, v);
142             add(v, d);
143         }
144         if (op[0] == '-') {
145             int u = rd, v = rd;
146             cut(u, v);
147             u = rd; v = rd;
148             link(u, v);
149         }
150         if (op[0] == '*') {
151             int u = rd, v = rd, d = rd;
152             split(u, v);
153             time(v, d);
154         }
155         if (op[0] == '/') {
156             int u = rd, v = rd;
157             split(u, v);
158             printf("%lld\n", sum[v] % mod);
159         }
160     }
161 }
Luogu1501 - 链修改模板

 

posted on 2018-09-20 20:22  cychester  阅读(204)  评论(0编辑  收藏  举报

导航