题意比较难理解,就是给你n个点的树,然后给你m个修改操作,每一次修改包括一个点对(x, y),意味着将x到y所有的点权值加一,最后问你整个树上的点权最大是多少。
比较裸的树链剖分了,感谢Haild的讲解。
首先第一遍dfs预处理出size,son(重儿子)。
第二遍dfs重编号。
然后线段树就可以了。
感觉就是把一棵树弄成一条一条的链,新奇的hash方法。
1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define drep(i, a, b) for (int i = a; i >= b; i--) 4 #define REP(i, a, b) for (int i = a; i < b; i++) 5 #define pb push_back 6 #define mp make_pair 7 #define clr(x) memset(x, 0, sizeof(x)) 8 #define xx first 9 #define yy second 10 using namespace std; 11 typedef long long i64; 12 typedef pair<int, int> pii; 13 const int inf = ~0U >> 1; 14 const i64 INF = ~0ULL >> 1; 15 //******************************* 16 17 template <typename T> void MAX(T &a, T &b) { if (a < b) a = b; } 18 template <typename T> void MIN(T &a, T &b) { if (a > b) a = b; } 19 20 const int maxn = 50005; 21 22 struct Ed { 23 int u, v, nx; Ed() {} 24 Ed(int _u, int _v, int _nx) : 25 u(_u), v(_v), nx(_nx) {} 26 } E[maxn << 1]; 27 int G[maxn], edtot; 28 void addedge(int u, int v) { 29 E[++edtot] = Ed(u, v, G[u]); 30 G[u] = edtot; 31 E[++edtot] = Ed(v, u, G[v]); 32 G[v] = edtot; 33 } 34 35 struct Seg_Tree { 36 int lazy[maxn << 2], Max[maxn << 2]; 37 void Push_down(int o) { 38 if (!lazy[o]) return; 39 lazy[o << 1] += lazy[o], lazy[o << 1 | 1] += lazy[o]; 40 Max[o << 1] += lazy[o], Max[o << 1 | 1] += lazy[o]; 41 lazy[o] = 0; 42 } 43 void Push_up(int o) { Max[o] = max(Max[o << 1], Max[o << 1 | 1]); } 44 void update(int o, int l, int r, int ql, int qr, int v) { 45 if (ql <= l && r <= qr) { 46 lazy[o] += v; 47 Max[o] += v; 48 return; 49 } 50 Push_down(o); 51 int mid = l + r >> 1; 52 if (ql <= mid) update(o << 1, l, mid, ql, qr, v); 53 if (qr > mid) update(o << 1 | 1, mid + 1, r, ql, qr, v); 54 Push_up(o); 55 } 56 } T; 57 58 int size[maxn], pre[maxn], son[maxn], dep[maxn]; 59 int dfs_size(int x, int fa) { 60 size[x] = 1; int haha = -inf; pre[x] = fa; dep[x] = dep[fa] + 1; 61 for (int i = G[x]; i; i = E[i].nx) if (E[i].v != fa) { 62 size[x] += dfs_size(E[i].v, x); 63 if (size[E[i].v] > haha) haha = size[E[i].v], son[x] = E[i].v; 64 } 65 return size[x]; 66 } 67 int ndtot, pos[maxn], top[maxn]; 68 void repos(int x, int tp) { 69 pos[x] = ++ndtot; 70 top[x] = tp; 71 if (son[x]) repos(son[x], tp); 72 for (int i = G[x]; i; i = E[i].nx) if (E[i].v != pre[x] && E[i].v != son[x]) repos(E[i].v, E[i].v); 73 } 74 75 int n; 76 void update(int x, int y) { 77 while (top[x] != top[y]) { 78 if (dep[top[x]] < dep[top[y]]) swap(x, y); 79 T.update(1, 1, n, pos[top[x]], pos[x], 1); x = pre[top[x]]; 80 } 81 T.update(1, 1, n, min(pos[x], pos[y]), max(pos[x], pos[y]), 1); 82 } 83 84 int main() { 85 freopen("maxflow.in", "r", stdin); 86 freopen("maxflow.out", "w", stdout); 87 int m; scanf("%d%d", &n, &m); 88 REP(i, 1, n) { 89 int x, y; scanf("%d%d", &x, &y); 90 addedge(x, y); 91 } 92 dfs_size(1, 1); 93 repos(1, 1); 94 while (m--) { 95 int x, y; scanf("%d%d", &x, &y); 96 update(x, y); 97 } 98 printf("%d\n", T.Max[1]); 99 return 0; 100 }