树链剖分

DFS_1要求出d，fa，son，siz

DFS_2要求出top，id(剖出来的下标)

 1 #include <cstdio>
2
3 const int N = 500010;
4
5 struct Edge {
6     int v, nex;
7 }edge[N << 1]; int t;
8 int e[N], A[N], root, num;
9 int top[N], son[N], fa[N], siz[N], id[N], d[N];
10
11 inline void add(int x, int y) {
12     t++;
13     edge[t].v = y;
14     edge[t].nex = e[x];
15     e[x] = t;
16     return;
17 }
18
19 void DFS_1(int x, int deep, int f) {
20     d[x] = deep;
21     siz[x] = 1;
22     fa[x] = f;
23     for(int i = e[x]; i; i = edge[i].nex) {
24         int y = edge[i].v;
25         if(y == f) {
26             continue;
27         }
28         DFS_1(y, deep + 1, x);
29         siz[x] += siz[y];
30         if(siz[y] > siz[son[x]]) {
31             son[x] = y;
32         }
33     }
34     return;
35 }
36
37 void DFS_2(int x, int k) {
38     top[x] = k;
39     id[x] = ++num;
40     A[num] = x;
41     if(son[x]) {
42         DFS_2(son[x], k);
43     }
44     for(int i = e[x]; i; i = edge[i].nex) {
45         int y = edge[i].v;
46         if(y == son[x] || y == fa[x]) {
47             continue;
48         }
49         DFS_2(y, y);
50     }
51     return;
52 }
53
54 inline int lca(int x, int y) {
55     while(top[x] != top[y]) {
56         if(d[top[x]] > d[top[y]]) {
57             x = fa[top[x]];
58         }
59         else {
60             y = fa[top[y]];
61         }
62     }
63     return d[x] > d[y] ? y : x;
64 }
65
66 int main() {
67     int n, m;
68     scanf("%d%d%d", &n, &m, &root);
69     int x, y;
70     for(int i = 1; i < n; i++) {
71         scanf("%d%d", &x, &y);
74     }
75     DFS_1(root, 1, 0);
76     DFS_2(root, root);
77     while(m--) {
78         scanf("%d%d", &x, &y);
79         printf("%d\n", lca(x, y));
80     }
81     return 0;
82 }
AC代码

HAOI2015 树上操作

  1 #include <cstdio>
2 typedef long long LL;
3 const int N = 100010;
4
5 struct Edge {
6     int v, nex;
7 }edge[N << 1]; int t;
8 int e[N], A[N], root, num;
9 int d[N], fa[N], top[N], son[N], id[N], siz[N];
10
11 int n;
12 LL sum[N << 2], tag[N << 2], val[N];
13
14 inline void add(int x, int y) {
15     t++;
16     edge[t].v = y;
17     edge[t].nex = e[x];
18     e[x] = t;
19     return;
20 }
21
22 void DFS_1(int x, int deep, int f) {
23     fa[x] = f;
24     siz[x] = 1;
25     d[x] = deep;
26     for(int i = e[x]; i; i = edge[i].nex) {
27         int y = edge[i].v;
28         if(y == f) {
29             continue;
30         }
31         DFS_1(y, deep + 1, x);
32         siz[x] += siz[y];
33         if(siz[y] > siz[son[x]]) {
34             son[x] = y;
35         }
36     }
37     return;
38 }
39
40 void DFS_2(int x, int k) {
41     top[x] = k;
42     id[x] = ++num;
43     A[num] = x;
44     if(son[x]) {
45         DFS_2(son[x], k);
46     }
47     for(int i = e[x]; i; i = edge[i].nex) {
48         int y = edge[i].v;
49         if(y == fa[x] || y == son[x]) {
50             continue;
51         }
52         DFS_2(y, y);
53     }
54     return;
55 }
56
57 inline void pushup(int l, int r, int o) {
58     if(l == r) {
59         return;
60     }
61     sum[o] = sum[o << 1] + sum[o << 1 | 1];
62     return;
63 }
64
65 inline void pushdown(int l, int r, int o) {
66     if(l == r) {
67         tag[o] = 0;
68         return;
69     }
70     if(!tag[o]) {
71         return;
72     }
73     int mid = (l + r) >> 1;
74     int ls = o << 1;
75     int rs = ls | 1;
76     LL k = tag[o];
77
78     tag[ls] += k;
79     tag[rs] += k;
80     sum[ls] += k * (mid - l + 1);
81     sum[rs] += k * (r - mid);
82
83     tag[o] = 0;
84     return;
85 }
86
87 inline void build(int l, int r, int o) {
88     if(l == r) {
89         sum[o] = val[A[r]];
90         return;
91     }
92     int mid = (l + r) >> 1;
93     build(l, mid, o << 1);
94     build(mid + 1, r, o << 1 | 1);
95     pushup(l, r, o);
96     return;
97 }
98
99 inline void add(int L, int R, LL v, int l, int r, int o) {
100     if(L <= l && r <= R) {
101         tag[o] += v;
102         sum[o] += v * (r - l + 1);
103         return;
104     }
105     pushdown(l, r, o);
106     int mid = (l + r) >> 1;
107     if(L <= mid) {
108         add(L, R, v, l, mid, o << 1);
109     }
110     if(mid < R) {
111         add(L, R, v, mid + 1, r, o << 1 | 1);
112     }
113     pushup(l, r, o);
114     return;
115 }
116
117 inline LL ask(int L, int R, int l, int r, int o) {
118     if(L <= l && r <= R) {
119         return sum[o];
120     }
121     if(r < L || R < l) {
122         return 0;
123     }
124     pushdown(l, r, o);
125     int mid = (l + r) >> 1;
126     return ask(L, R, l, mid, o << 1) + ask(L, R, mid + 1, r, o << 1 | 1);
127 }
128
129 inline LL ask(int x) {
130     LL ans = 0;
131     while(top[x] != root) {
132         ans += ask(id[top[x]], id[x], 1, n, 1);
133         x = fa[top[x]];
134     }
135     ans += ask(id[root], id[x], 1, n, 1);
136     return ans;
137 }
138
139 int main() {
140     int m;
141     scanf("%d%d", &n, &m);
142     for(int i = 1; i <= n; i++) {
143         scanf("%lld", &val[i]);
144     }
145     root = 1;
146     int x, f;
147     LL y;
148     for(int i = 1; i < n; i++) {
149         scanf("%d%d", &x, &y);
152     }
153     DFS_1(root, 1, 0);
154     DFS_2(root, root);
155     build(1, n, 1);
156     while(m--) {
157         scanf("%d", &f);
158         if(f == 1) {
159             scanf("%d%lld", &x, &y);
160             add(id[x], id[x], y, 1, n, 1);
161         }
162         else if(f == 2) {
163             scanf("%d%lld", &x, &y);
164             add(id[x], id[x] + siz[x] - 1, y, 1, n, 1);
165         }
166         else {
167             scanf("%d", &x);
169         }
170     }
171     return 0;
172 }
AC代码

  1 #include <cstdio>
2
3 const int N = 300010;
4
5 struct Edge {
6     int v, nex;
7 }edge[N << 1]; int t;
8 int e[N], d[N], siz[N], son[N], fa[N], id[N], top[N];
9 int num, A[N], B[N], sum[N << 2], n;
10
11 inline void add(int x, int y) {
12     t++;
13     edge[t].v = y;
14     edge[t].nex = e[x];
15     e[x] = t;
16     return;
17 }
18
19 void DFS_1(int x, int deep, int f) {
20     siz[x] = 1;
21     fa[x] = f;
22     d[x] = deep;
23     for(int i = e[x]; i; i = edge[i].nex) {
24         int y = edge[i].v;
25         if(y == f) {
26             continue;
27         }
28         DFS_1(y, deep + 1, x);
29         siz[x] += siz[y];
30         if(siz[y] > siz[son[x]]) {
31             son[x] = y;
32         }
33     }
34     return;
35 }
36
37 void DFS_2(int x, int k) {
38     top[x] = k;
39     id[x] = ++num;
40     A[num] = x;
41     if(son[x]) {
42         DFS_2(son[x], k);
43     }
44     for(int i = e[x]; i; i = edge[i].nex) {
45         int y = edge[i].v;
46         if(y == fa[x] || y == son[x]) {
47             continue;
48         }
49         DFS_2(y, y);
50     }
51     return;
52 }
53
54 inline void pushup(int l, int r, int o) {
55     if(l == r) {
56         return;
57     }
58     sum[o] = sum[o << 1] + sum[o << 1 | 1];
59     return;
60 }
61
62 void build(int l, int r, int o) {
63     if(l == r) {
64         sum[o] = 0;
65         return;
66     }
67     int mid = (l + r) >> 1;
68     build(l, mid, o << 1);
69     build(mid + 1, r, o << 1 | 1);
70     pushup(l, r, o);
71     return;
72 }
73
74 int ask(int L, int R, int l, int r, int o) {
75     if(L <= l && r <= R) {
76         return sum[o];
77     }
78     if(r < L || R < l) {
79         return 0;
80     }
81     int mid = (l + r) >> 1;
82     return ask(L, R, l, mid, o << 1) + ask(L, R, mid + 1, r, o << 1 | 1);
83 }
84
85 void change(int p, int a, int l, int r, int o) {
86     if(l == r) {
87         sum[o] = a;
88         return;
89     }
90     int mid = (l + r) >> 1;
91     if(p <= mid) {
92         change(p, a, l, mid, o << 1);
93     }
94     else {
95         change(p, a, mid + 1, r, o << 1 | 1);
96     }
97     pushup(l, r, o);
98     return;
99 }
100
101 inline int ask(int x) {
102     int ans = 0;
103     while(x) {
104         ans += ask(id[top[x]], id[x], 1, n, 1);
105         x = fa[top[x]];
106     }
107     return ans;
108 }
109
110 inline int lca(int x, int y) {
111     while(top[x] != top[y]) {
112         if(d[top[x]] > d[top[y]]) {
113             x = fa[top[x]];
114         }
115         else {
116             y = fa[top[y]];
117         }
118     }
119     return d[x] > d[y] ? y : x;
120 }
121
122 int main() {
123     int m, x, y;
124     char c[20];
125     scanf("%d%d", &n, &m);
126     for(int i = 1; i < n; i++) {
127         scanf("%d%d", &x, &y);
130     }
131     DFS_1(1, 1, 0);
132     DFS_2(1, 1);
133     build(1, n, 1);
134     num = 0;
135     for(int i = 1; i <= m; i++) {
136         scanf("%s", c);
137         scanf("%d", &x);
138         if(c[0] == 'Q') {
139             scanf("%d", &y);
141             if(t) {
142                 printf("No\n");
143             }
144             else {
145                 printf("Yes\n");
146             }
147         }
148         else if(c[0] == 'C') {
149             scanf("%d", &y);
150             A[++num] = x;
151             B[num] = y;
152             if(fa[y] == x) {
153                 x = y;
154             }
155             change(id[x], 1, 1, n, 1);
156         }
157         else {
158             y = A[x];
159             x = B[x];
160             if(fa[y] == x) {
161                 x = y;
162             }
163             change(id[x], 0, 1, n, 1);
164         }
165     }
166     return 0;
167 }
AC代码

posted @ 2018-07-23 20:49  garage  阅读(...)  评论(...编辑  收藏