洛谷P4719 【模板】动态 DP 题解 动态DP(DDP)模板题
题目链接:https://www.luogu.com.cn/problem/P4719
解题思路:完全来自 oi.wiki
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5, inf = 1e9;
int f[maxn][2];
int n, m, a[maxn];
int dfn[maxn], id[maxn], ts, fa[maxn], top[maxn], End[maxn], sz[maxn], son[maxn];
vector<int> g[maxn];
struct Matrix {
int a[2][2];
Matrix() {
memset(a, 0, sizeof a);
}
Matrix operator * (const Matrix &b) const {
Matrix c;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
c.a[i][j] = max(a[i][0] + b.a[0][j], a[i][1] + b.a[1][j]);
return c;
}
} tr[maxn<<2], G[maxn];
#define lson l, mid, u<<1
#define rson mid+1, r, u<<1|1
void push_up(int u) {
tr[u] = tr[u<<1] * tr[u<<1|1];
}
void build(int l, int r, int u) {
if (l == r) {
tr[u] = G[ id[l] ];
return;
}
int mid = l + r >> 1;
build(lson);
build(rson);
push_up(u);
}
Matrix query(int L, int R, int l, int r, int u) {
if (L <= l && r <= R)
return tr[u];
int mid = l + r >> 1;
if (L <= mid && R > mid)
return query(L, R, lson) * query(L, R, rson);
else if (L <= mid)
return query(L, R, lson);
else {
assert(R > mid);
return query(L, R, rson);
}
}
void update(int p, int l, int r, int u) {
if (l == r) {
tr[u] = G[ id[l] ];
return;
}
int mid = l + r >> 1;
(p <= mid) ? update(p, lson) : update(p, rson);
push_up(u);
}
void Update(int x, int val) {
G[x].a[1][0] += val - a[x];
a[x] = val;
while (x) {
Matrix last = query(dfn[ top[x] ], End[ top[x] ], 1, n, 1);
update(dfn[x], 1, n, 1);
Matrix now = query(dfn[ top[x] ], End[ top[x] ], 1, n, 1);
x = fa[ top[x] ];
if (!x)
break;
G[x].a[0][0] += max(now.a[0][0], now.a[1][0]) - max(last.a[0][0], last.a[1][0]);
G[x].a[0][1] = G[x].a[0][0];
G[x].a[1][0] += now.a[0][0] - last.a[0][0];
}
}
void dfs1(int u, int p) {
fa[u] = p;
f[u][1] = a[u];
f[u][0] = 0;
sz[u] = 1;
for (auto v : g[u]) {
if (v != p) {
dfs1(v, u);
f[u][1] += f[v][0];
f[u][0] += max(f[v][1], f[v][0]);
sz[u] += sz[v];
if (sz[v] > sz[ son[u] ])
son[u] = v;
}
}
}
void dfs2(int u, int tp) {
dfn[u] = ++ts;
id[ts] = u;
top[u] = tp;
End[tp] = ts;
if (son[u])
dfs2(son[u], tp);
G[u].a[1][0] = a[u];
G[u].a[1][1] = -inf;
for (auto v : g[u]) {
if (v != son[u] && v != fa[u]) {
dfs2(v, v);
G[u].a[0][0] += max(f[v][1], f[v][0]);
G[u].a[1][0] += f[v][0];
}
}
G[u].a[0][1] = G[u].a[0][0];
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", a+i);
for (int i = 1, u, v; i < n; i++) {
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(1, 0);
dfs2(1, 1);
build(1, n, 1);
for (int i = 0, x, y; i < m; i++) {
scanf("%d%d", &x, &y);
Update(x, y);
Matrix res = query(1, End[1], 1, n, 1);
int ans = max(res.a[0][0], res.a[1][0]);
printf("%d\n", ans);
}
return 0;
}
```
浙公网安备 33010602011771号