在修改、查询的代码中,有注释的几行代码,还有上面的一行代码,想问为什么上面的哪行代码是对的。
拿查询举例,现在想要查询 u , v 两个节点之间的最大值。
可是idx[x]+1可能不是 u , v 之间的那个 lca 的儿子的那个节点。因为idx[x]+1显然是 lca节点dfs的第一个节点, 所以idx[x]+1可能并不是 u 、v 之间的节点,有可能会多算边。
但实际上两种写法都能ac
#include <bits/stdc++.h>
using namespace std;
const int maxN = 1e5 + 7;
int st[maxN], ed[maxN], dis[maxN];
int V[maxN];
vector<int> E[maxN];
int cnt, rk[maxN], idx[maxN];
int fa[maxN], top[maxN], siz[maxN], son[maxN], dep[maxN];
void dfs1(int x, int f) {
siz[x] = 1;
dep[x] = dep[f] + 1;
fa[x] = f;
for (auto to : E[x]) {
if (to == f) continue;
dfs1(to, x);
siz[x] += siz[to];
if (siz[to] > siz[son[x]]) son[x] = to;
}
}
void dfs2(int x, int tp) {
top[x] = tp;
idx[x] = ++cnt;
rk[cnt] = x;
if (!son[x]) return;
dfs2(son[x], tp);
for (auto to : E[x]) {
if (to == fa[x] || to == son[x]) continue;
dfs2(to, to);
}
}
struct Tree {
int l, r;
int v;
int tg, lz;
} t[maxN << 2];
#define ls (cur << 1)
#define rs (cur << 1 | 1)
void upd(int cur) {
t[cur].v = max(t[ls].v, t[rs].v);
}
void build(int L, int R, int cur) {
t[cur].l = L;
t[cur].r = R;
if (L == R) {
t[cur].v = dis[rk[L]];
return;
}
int mid = (L + R) >> 1;
build(L, mid, ls);
build(mid + 1, R, rs);
upd(cur);
}
void M(Tree &res, int tg, int lz) {
if (lz) res.v = lz, res.lz = lz, res.tg = 0;
if (tg) res.v += tg, res.tg += tg;
}
void down(int cur) {
if (!t[cur].lz && !t[cur].tg) return;
M(t[ls], t[cur].tg, t[cur].lz);
M(t[rs], t[cur].tg, t[cur].lz);
t[cur].lz = t[cur].tg = 0;
}
void modify(int L, int R, int V, int cur, int type) {
if (L <= t[cur].l && t[cur].r <= R) {
if (type == 1) {
t[cur].tg = 0;
t[cur].lz = V;
t[cur].v = V;
}
if (type == 2) {
t[cur].tg += V;
t[cur].v += V;
}
} else {
down(cur);
int mid = (t[cur].l + t[cur].r) >> 1;
if (L <= mid) modify(L, R, V, ls, type);
if (R > mid) modify(L, R, V, rs, type);
upd(cur);
}
}
int query(int L, int R, int cur) {
if (L <= t[cur].l && t[cur].r <= R) return t[cur].v;
down(cur);
int mid = (t[cur].l + t[cur].r) >> 1, res = -2e9;
if (L <= mid) res = max(res, query(L, R, ls));
if (R > mid) res = max(res, query(L, R, rs));
return res;
}
void R1(int x, int y, int z) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
modify(idx[top[x]], idx[x], z, 1, 1);
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
modify(idx[x] + 1, idx[y], z, 1, 1);
// int now = rk[idx[x] + 1];
// while (top[y] != top[now]) now += siz[now];
// modify(idx[now], idx[y], z, 1, 1);
}
void R2(int x, int y, int z) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
modify(idx[top[x]], idx[x], z, 1, 2);
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
modify(idx[x] + 1, idx[y], z, 1, 2);
// int now = rk[idx[x] + 1];
// while (top[y] != top[now]) now += siz[now];
// modify(idx[now], idx[y], z, 1, 2);
}
void R3(int x, int y) {
int ans = -2e9;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
ans = max(ans, query(idx[top[x]], idx[x], 1));
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
ans = max(ans, query(idx[x] + 1, idx[y], 1));
// int now = rk[idx[x] + 1];
// while (top[y] != top[now]) now += siz[now];
// ans = max(ans, query(idx[now], idx[y], 1));
cout << ans << '\n';
}
int n;
int main() {
// freopen("P4315_1.in", "r", stdin);
// freopen("P4315_1.ans", "w", stdout);
cin >> n;
for (int i = 1; i < n; i++) {
cin >> st[i] >> ed[i] >> V[i];
int x = st[i], y = ed[i];
E[x].push_back(y);
E[y].push_back(x);
}
dfs1(1, 0);
dfs2(1, 1);
for (int i = 1; i < n; i++) {
int fx = idx[st[i]], fy = idx[ed[i]];
if (fx < fy) dis[ed[i]] = V[i], V[i] = ed[i];
else dis[st[i]] = V[i], V[i] = st[i];
}
build(1, n, 1);
string s;
do {
cin >> s;
if (s == "Change") {
int k, w;
cin >> k >> w;
modify(idx[V[k]], idx[V[k]], w, 1, 1);
}
if (s == "Cover") {
int x, y, z;
cin >> x >> y >> z;
R1(x, y, z);
}
if (s[0] == 'A') {
int x, y, z;
cin >> x >> y >> z;
R2(x, y, z);
}
if (s[0] == 'M') {
int x, y;
cin >> x >> y;
R3(x, y);
}
} while (s != "Stop");
}
/*
5
1 2 9
1 4 5
2 3 7
2 5 7
Max 2 3
Cover 1 4 14
Add 2 5 7
Max 1 5
Stop
5
1 2 1
1 3 3
1 4 9
3 5 7
Cover 5 4 1
Max 5 4
Stop
10
1 2 3
1 3 9
1 4 88
1 9 56
2 5 6
2 6 1
5 7 4
9 8 7
9 10 55
Max 7 10
Cover 7 8 999
Max 7 10
Cover 7 8 1
Max 3 8
Stop
*/