树上差分

首先,树上差分是从子节点推到根节点,定义 dd 差分数组

若修改 (x,y)(x,y) 路径上的点权,则 dx,dy+=k,dlca,dfalca=kd_x, d_y \mathrel{+}= k, d_{\mathrm{lca}}, d_{\mathrm{fa}_{\mathrm{lca}}} \mathrel{-}= k

1
2
3
4
5
6
void dfs(int u){
val[u] = d[u];
for (auto v : g[u]){
dfs(v), val[u] += val[v];
}
}

若修改 (x,y)(x,y) 路径上的边权,则 dx,dy+=k,dlca=2kd_x, d_y \mathrel{+}= k, d_{\mathrm{lca}}\mathrel{-}= 2k

1
2
3
4
5
6
7
8
int dfs(int u){
int ret = d[u];
for (auto i : g[u]){
i.w = dfs(i.v);
ret += i.w;
}
return ret;
}

P3128 最大流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
#define per(i, l, r) for (int i = (l); i >= (r); --i)
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::make_pair;
using std::pair;
typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned int ui;

const int N = 50010;

std::vector<int> g[N];

int d[N], fa[20][N], dep[N], val[N];

void dfs(int u) {
for (auto v : g[u]) {
if (v == fa[0][u]) continue;
fa[0][v] = u;
dep[v] = dep[u] + 1;
dfs(v);
}
}

int up(int u, int l) {
for (int i = 19; i >= 0; --i) {
if (l >= (1 << i)) u = fa[i][u], l -= 1 << i;
}
return u;
}

int q(int u, int v) {
if (dep[u] < dep[v]) std::swap(u, v);
u = up(u, dep[u] - dep[v]);
if (u == v) return u;
for (int i = 19; i >= 0; --i)
if (fa[i][u] != fa[i][v]) u = fa[i][u], v = fa[i][v];
return fa[0][u];
}

void calc(int u) {
val[u] = d[u];
for (auto v : g[u]) {
if (v == fa[0][u]) continue;
calc(v), val[u] += val[v];
}
}

int main() {
#ifdef LOCAL
freopen("input", "r", stdin);
#endif
std::ios::sync_with_stdio(false);
cout.tie(0);
int n, k, u, v;
cin >> n >> k;
rep(i, 2, n) {
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dep[1] = 1, dfs(1);
rep(k, 1, 19) rep(i, 1, n) fa[k][i] = fa[k - 1][fa[k - 1][i]];
rep(i, 1, k) {
cin >> u >> v;
int lca = q(u, v);
d[u] += 1, d[v] += 1, d[lca] -= 1, d[fa[0][lca]] -= 1;
}
calc(1);
int ans = 0;
rep(i, 1, n) ans = std::max(ans, val[i]);
cout << ans;
return 0;
}
作者

Gesrua

发布于

2019-07-16

更新于

2020-11-21

许可协议