# 树链剖分(轻重链剖分)算法笔记

-------------------------------------------------------------------------------------------

  1 #include <cstdio>
2 #include <cstring>
3 #include <cmath>
4 #include <algorithm>
5 using namespace std;
6 const int N = 1e4 + 10;
7 int firste[N], nexte[N << 1], v[N << 1], w[N << 1];
8 int fa[N], d[N], sz[N], son[N];
9 int id[N], top[N], up[N], down[N];
10 int mx[N << 2];
11 char s[20];
12 int t, n, e, cnt;
13 void build(int x, int y, int z)
14 {
15     nexte[++e] = firste[x];
16     firste[x] = e;
17     v[e] = y;
18     w[e] = z;
19 }
20 void dfs1(int u)
21 {
22     sz[u] = 1;
23     for(int p = firste[u]; p; p = nexte[p])
24         if(v[p] != fa[u])
25         {
26             fa[v[p]] = u;
27             d[v[p]] = d[u] + 1;
28             down[p >> 1] = v[p];
29             dfs1(v[p]);
30             sz[u] += sz[v[p]];
31             if(sz[v[p]] > sz[son[u]])
32                 son[u] = v[p];
33         }
34 }
35 void dfs2(int u)
36 {
37     id[u] = ++cnt;
38     if(son[u])
39     {
40         top[son[u]] = top[u];
41         dfs2(son[u]);
42     }
43     for(int p = firste[u]; p; p = nexte[p])
44         if(v[p] != fa[u] && v[p] != son[u])
45         {
46             top[v[p]] = v[p];
47             dfs2(v[p]);
48         }
49 }
50 void update(int x, int L, int R, int tl, int tr, int y)
51 {
52     if(L == tl && tr == R)
53     {
54         mx[x] = y;
55         return;
56     }
57     int mid = (tl + tr) >> 1;
58     if(L < mid)
59         update(x << 1, L, R, tl, mid, y);
60     else
61         update(x << 1 | 1, L, R, mid, tr, y);
62     mx[x] = max(mx[x << 1], mx[x << 1 | 1]);
63 }
64 int query(int x, int L, int R, int tl, int tr)
65 {
66     if(L == R)
67         return 0;
68     if(L <= tl && tr <= R)
69         return mx[x];
70     int mid = (tl + tr) >> 1, re = 0;
71     if(L < mid)
72         re = max(re, query(x << 1, L, R, tl, mid));
73     if(mid < R)
74         re = max(re, query(x << 1 | 1, L, R, mid, tr));
75     return re;
76 }
77 int main()
78 {
79     scanf("%d", &t);
80     while(t--)
81     {
82         e = 1;
83         memset(firste, 0, sizeof firste);
84         memset(fa, 0, sizeof fa);
85         memset(d, 0, sizeof d);
86         memset(sz, 0, sizeof sz);
87         memset(son, 0, sizeof son);
88         memset(id, 0, sizeof id);
89         memset(top, 0, sizeof top);
90         memset(up, 0, sizeof up);
91         memset(down, 0, sizeof down);
92         memset(mx, 0, sizeof mx);
93         cnt = 0;
94         top[1] = 1;
95         scanf("%d", &n);
96         int x, y, z;
97         for(int i = 1; i < n; ++i)
98         {
99             scanf("%d%d%d", &x, &y, &z);
100             build(x, y, z);
101             build(y, x, z);
102         }
103         dfs1(1);
104         dfs2(1);
105         for(int i = 2; i < (n << 1); i += 2)
106         {
107             int l = id[v[i]], r = id[v[i ^ 1]];
108             if(l > r)
109                 swap(l, r);
110             if(r - l == 1)
111                 update(1, l, r, 1, cnt, w[i]);
112             else
113             {
114                 if(id[v[i]] > id[v[i ^ 1]])
115                     up[v[i]] = w[i];
116                 else
117                     up[v[i ^ 1]] = w[i];
118             }
119         }
120         while(scanf("%s", s), s[0] != 'D')
121         {
122             if(s[0] == 'Q')
123             {
124                 int ans = 0, x, y;
125                 scanf("%d%d", &x, &y);
126                 while(top[x] != top[y])
127                 {
128                     if(d[top[x]] < d[top[y]])
129                         swap(x, y);
130                     ans = max(ans, query(1, id[top[x]], id[x], 1, cnt));
131                     x = top[x];
132                     ans = max(ans, up[x]);
133                     x = fa[x];
134                 }
135                 if(d[x] < d[y])
136                     swap(x, y);
137                 ans = max(ans, query(1, id[y], id[x], 1, cnt));
138                 printf("%d\n", ans);
139             }
140             else
141             {
142                 int x, y;
143                 scanf("%d%d", &x, &y);
144                 x = down[x];
145                 if(top[x] != x)
146                     update(1, id[fa[x]], id[x], 1, cnt, y);
147                 else
148                     up[x] = y;
149             }
150         }
151     }
152     return 0;
153 }

posted @ 2016-07-11 16:43 sagitta 阅读(...) 评论(...) 编辑 收藏