RT,应该写得够清楚了,样例第一个输出 0 第二个没错,麻烦大佬帮忙调一下,谢谢
#include <bits/stdc++.h>
using namespace std;
#define lc(x) x<<1
#define rc(x) x<<1|1
int n, p, x, y, z, w[100010], h[200010]; string st;
int f[100010], dfn[100010], dep[100010], siz[100010], top[100010], son[100010], rnk[100010];
struct node{
int x, y, z, next;
}a[200010];
void add(int x, int y, int z){
a[++p].x = x, a[p].y = y, a[p].z = z, a[p].next = h[x], h[x] = p;
}
void dfs1(int x, int fa){
f[x] = fa, dep[x] = dep[fa] + 1, siz[x] = 1;
for (int i=h[x]; i; i=a[i].next){
int y = a[i].y, val = a[i].z;
if (y == fa) continue;
w[y] = val;
dfs1(y, x);
siz[x] += siz[y];
if (siz[y] > siz[son[x]]) son[x] = y;
}
}
void dfs2(int x, int tp){
dfn[x] = ++dfn[0];
top[x] = tp;
rnk[dfn[0]] = w[x];
if (!son[x]) return ;
dfs2(son[x], tp);
for (int i=h[x]; i; i=a[i].next){
int y = a[i].y;
if (y == f[x] || y == son[x]) continue;
dfs2(y, y);
}
}
int d[400010], tag[400010], cg[400010];
void pushup(int k){
d[k] = max(d[lc(k)], d[rc(k)]);
}
void pushdown(int k){
if (cg[k] != -1){
cg[lc(k)] = cg[rc(k)] = d[lc(k)] = d[rc(k)] = cg[k];
tag[lc(k)] = tag[rc(k)] = 0;
cg[k] = -1;
}
if (tag[k]){
tag[lc(k)] += tag[k];
tag[rc(k)] += tag[k];
d[lc(k)] += tag[k];
d[rc(k)] += tag[k];
tag[k] = 0;
}
}
void build(int k, int l, int r){
if (l == r){
d[l] = w[l];
return ;
}
int mid = l + r >> 1;
build(lc(k), l, mid);
build(rc(k), mid+1, r);
pushup(k);
}
void change(int k, int l, int r, int x, int y, int p){
if (x <= l && r <= y){
d[k] = p, cg[k] = p, tag[k] = 0;
return ;
}
pushdown(k);
int mid = l + r >> 1;
if (x <= mid) change(lc(k), l, mid, x, y, p);
if (y > mid) change(rc(k), mid+1, r, x, y, p);
pushup(k);
}
void add(int k, int l, int r, int x, int y, int p){
if (x <= l && r <= y){
d[k] += p, tag[k] += p;
return ;
}
pushdown(k);
int mid = l + r >> 1;
if (x <= mid) change(lc(k), l, mid, x, y, p);
if (y > mid) change(rc(k), mid+1, r, x, y, p);
pushup(k);
}
int query(int k, int l, int r, int x, int y){
if (x <= l && r <= y) return d[k];
pushdown(k);
int mid = l + r >> 1, ret = -1e9-7;
if (x <= mid) ret = max(ret, query(lc(k), l, mid, x, y));
if (y > mid) ret = max(ret, query(rc(k), mid+1, r, x, y));
return ret;
}
void changeT(int x, int y, int z){
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swap(x, y);
change(1, 1, n, dfn[top[x]], dfn[x], z);
x = f[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
change(1, 1, n, dfn[x]+1, dfn[y], z);//dfn[x]+1即是边权转化为点权
}
void addT(int x, int y, int z){
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swap (x, y);
add(1, 1, n, dfn[top[x]], dfn[x], z);
x = f[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
add(1, 1, n, dfn[x]+1, dfn[y], z);
}
int queryT(int x, int y){
int res = -1e9 - 7;
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swap(x, y);
res = max(res, query(1, 1, n, dfn[top[x]], dfn[x]));
x = f[top[x]];
}
if (dfn[x] > dfn[y]) swap(x, y);
return res = max(res, query(1, 1, n, dfn[x]+1, dfn[y]));
}
int main(){
memset(cg, -1, sizeof(cg));
scanf ("%d", &n);
for (int i=1; i<n; i++){
scanf ("%d%d%d", &x, &y, &z);
add(x, y, z); add(y, x, z);
}
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
while (cin >> st){
if (st == "Stop") return 0;
if (st == "Max"){
scanf ("%d%d", &x, &y);
printf ("%d\n", queryT(x, y));
}
else if (st == "Add"){
scanf ("%d%d%d", &x, &y, &z);
addT(x, y, z);
}
else if (st == "Cover"){
scanf ("%d%d%d", &x, &y, &z);
changeT(x, y, z);
}
else{
scanf ("%d%d", &x, &z);
int X = a[x*2].x, Y = a[x*2].y;
if (dep[X] > dep[Y]) swap(X, Y);
changeT(X, Y, z);
}
}
return 0;
}