【HDU】4010 Query on The Trees

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<iostream>
  5 #include<algorithm>
  6 #define MAXN 300010
  7 #define MAXM 600010
  8 #define CLEAR(a,b) memset(a,b,sizeof(a))
  9 using namespace std;
 10 int first[MAXN], next[MAXM], v[MAXM], e;
 11 bool vis[MAXN];
 12 struct LCT {
 13     int bef[MAXN];
 14     bool flip[MAXN];
 15     int next[MAXN][2], pre[MAXN], key[MAXN], add[MAXN], maxi[MAXN];
 16     void Init() {
 17         CLEAR(next, 0);
 18         CLEAR(pre, 0);
 19         flip[0] = flip[1] = false;
 20         add[0] = add[1] = 0;
 21         bef[0] = bef[1] = 0;
 22         key[0] = maxi[0] = 0;
 23     }
 24     inline void PushUp(int x) {
 25         maxi[x] = max(key[x], max(maxi[next[x][0]], maxi[next[x][1]]));
 26     }
 27     inline void Inc(int x, int val) {
 28         if (x) {
 29             add[x] += val;
 30             key[x] += val;
 31             maxi[x] += val;
 32         }
 33     }
 34     inline void PushDown(int x) {
 35         if (add[x]) {
 36             Inc(next[x][0], add[x]);
 37             Inc(next[x][1], add[x]);
 38             add[x] = 0;
 39         }
 40         if (flip[x]) {
 41             flip[next[x][0]] ^= true;
 42             flip[next[x][1]] ^= true;
 43             swap(next[x][0], next[x][1]);
 44             flip[x] = false;
 45         }
 46     }
 47     void Rotate(int x, int kind) {
 48         int y, z;
 49         y = pre[x];
 50         z = pre[y];
 51         PushDown(x);
 52         next[y][!kind] = next[x][kind];
 53         pre[next[x][kind]] = y;
 54         next[z][next[z][1] == y] = x;
 55         pre[x] = z;
 56         next[x][kind] = y;
 57         pre[y] = x;
 58         PushUp(y);
 59     }
 60     void Splay(int x) {
 61         int rt;
 62         for (rt = x; pre[rt]; rt = pre[rt])
 63             ;
 64         if (rt != x) {
 65             bef[x] = bef[rt];
 66             bef[rt] = 0;
 67             while (pre[x]) {
 68                 PushDown(pre[x]);
 69                 if (next[pre[x]][0] == x)
 70                     Rotate(x, 1);
 71                 else
 72                     Rotate(x, 0);
 73             }
 74             PushUp(x);
 75         } else
 76             PushDown(x);
 77     }
 78     void Access(int x) {
 79         int father;
 80         for (father = 0; x; x = bef[x]) {
 81             Splay(x);
 82             bef[next[x][1]] = x;
 83             pre[next[x][1]] = 0;
 84             next[x][1] = father;
 85             pre[father] = x;
 86             bef[father] = 0;
 87             father = x;
 88             PushUp(x);
 89         }
 90     }
 91     int GetRoot(int x) {
 92         Access(x);
 93         Splay(x);
 94         while (next[x][0])
 95             x = next[x][0];
 96         return x;
 97     }
 98     void MakeRoot(int x) {
 99         Access(x);
100         Splay(x);
101         flip[x] ^= true;
102     }
103     void Join(int x, int y) {
104         MakeRoot(x);
105         MakeRoot(y);
106         bef[x] = y;
107     }
108     void Cut(int x) {
109         Access(x);
110         Splay(x);
111         bef[next[x][0]] = bef[x];
112         bef[x] = 0;
113         pre[next[x][0]] = 0;
114         next[x][0] = 0;
115         PushUp(x);
116     }
117     void Update(int x, int y, int val) {
118         Access(y);
119         for (y = 0; x; x = bef[x]) {
120             Splay(x);
121             if (!bef[x]) {
122                 key[x] += val;
123                 Inc(y, val);
124                 Inc(next[x][1], val);
125                 return;
126             }
127             bef[next[x][1]] = x;
128             pre[next[x][1]] = 0;
129             next[x][1] = y;
130             pre[y] = x;
131             bef[y] = 0;
132             y = x;
133             PushUp(x);
134         }
135     }
136     int Query(int x, int y) {
137         Access(y);
138         for (y = 0; x; x = bef[x]) {
139             Splay(x);
140             if (!bef[x])
141                 return max(key[x], max(maxi[next[x][1]], maxi[y]));
142             bef[next[x][1]] = x;
143             pre[next[x][1]] = 0;
144             next[x][1] = y;
145             pre[y] = x;
146             bef[y] = 0;
147             y = x;
148             PushUp(x);
149         }
150         return -1;
151     }
152 } lct;
153 int INT() {
154     int res;
155     char ch;
156     while (ch = getchar(), !isdigit(ch))
157         ;
158     for (res = ch - '0'; ch = getchar(), isdigit(ch);)
159         res = res * 10 + ch - '0';
160     return res;
161 }
162 inline void AddEdge(int x, int y) {
163     v[e] = y;
164     next[e] = first[x];
165     first[x] = e++;
166 }
167 void BFS(int x) {
168     int i, y;
169     queue<int> q;
170     memset(vis, false, sizeof(vis));
171     vis[x] = true;
172     q.push(x);
173     while (!q.empty()) {
174         x = q.front();
175         q.pop();
176         for (i = first[x]; i != -1; i = next[i]) {
177             y = v[i];
178             if (!vis[y]) {
179                 lct.bef[y] = x;
180                 lct.add[y] = 0;
181                 lct.flip[y] = false;
182                 vis[y] = true;
183                 q.push(y);
184             }
185         }
186     }
187 }
188 int main() {
189     int n, i, q;
190     int cmd, x, y, val;
191     while (~scanf("%d", &n)) {
192         lct.Init();
193         memset(first, -1, sizeof(first));
194         for (e = 0, i = 1; i < n; i++) {
195             x = INT(), y = INT();
196             AddEdge(x, y);
197             AddEdge(y, x);
198         }
199         BFS(1);
200         for (i = 1; i <= n; i++)
201             lct.key[i] = INT();
202         q = INT();
203         while (q--) {
204             cmd = INT();
205             if (cmd == 1) {
206                 x = INT(), y = INT();
207                 if (lct.GetRoot(x) == lct.GetRoot(y))
208                     puts("-1");
209                 else
210                     lct.Join(x, y);
211             } else if (cmd == 2) {
212                 x = INT(), y = INT();
213                 if (x == y || lct.GetRoot(x) != lct.GetRoot(y))
214                     puts("-1");
215                 else {
216                     lct.MakeRoot(x);
217                     lct.Cut(y);
218                 }
219             } else if (cmd == 3) {
220                 val = INT(), x = INT(), y = INT();
221                 if (lct.GetRoot(x) != lct.GetRoot(y))
222                     puts("-1");
223                 else
224                     lct.Update(x, y, val);
225             } else {
226                 x = INT(), y = INT();
227                 if (lct.GetRoot(x) != lct.GetRoot(y))
228                     puts("-1");
229                 else
230                     printf("%d\n", lct.Query(x, y));
231             }
232         }
233         putchar('\n');
234     }
235     return 0;
236 }
原文地址:https://www.cnblogs.com/DrunBee/p/2657820.html