rt,请dalao帮忙看看
#include <bits/stdc++.h>
#define ls(x) x << 1
#define rs(x) (x << 1) | 1
const int sp = 1e6 + 5;
struct sg_tr{
int l, r, dat;
}tr[sp];
int tag1[sp], tag2[sp];
int dep[sp], fa[sp], hson[sp], siz[sp];
int tp[sp];
int id[sp], tot;
int u[sp], v[sp], w[sp], ww[sp], tmp[sp];
int n;
std::string s;
std::vector <int> mp[sp];
void get_info(int x, int f){
fa[x] = f;
dep[x] = dep[f] + 1;
siz[x] = 1;
int maxn = 0;
for(int i = 0; i < mp[x].size(); ++ i){
int y = mp[x][i];
if(y == f){
continue;
}
get_info(y, x);
siz[x] += siz[y];
if(siz[y] > maxn){
maxn = siz[y];
hson[x] = y;
}
}
return;
}
void get_tp(int x, int ttp){
tp[x] = ttp;
id[x] = ++ tot;
w[id[x]] = ww[x];
if(hson[x] == 0){
return;
}
get_tp(hson[x], ttp);
for(int i = 0; i < mp[x].size(); ++ i){
int y = mp[x][i];
if(y == fa[x] || y == hson[x]){
continue;
}
get_tp(y, y);
}
return;
}
void pushup(int p){
tr[p].dat = std::max(tr[ls(p)].dat, tr[rs(p)].dat);
return;
}
void build(int p, int l, int r){
tr[p].l = l, tr[p].r = r;
if(l == r){
tr[p].dat = w[l];
return;
}
int mid = (l + r) >> 1;
build(ls(p), l, mid);
build(rs(p), mid + 1, r);
pushup(p);
return;
}
void tagdown1(int p){
tag1[ls(p)] = tag1[rs(p)] = tag1[p];
tr[ls(p)].dat = tr[rs(p)].dat = tag1[p];
tag1[p] = -1;
return;
}
void tagdown2(int p){
tag2[ls(p)] += tag2[p];
tag2[rs(p)] += tag2[p];
tr[ls(p)].dat += tag2[p];
tr[rs(p)].dat += tag2[p];
tag2[p] = 0;
return;
}
void update1(int p, int dl, int dr, int k){
if(tr[p].l > dr || tr[p].r < dl){
return;
}
if(tag1[p] != -1){
tagdown1(p);
}
if(tag2[p] != 0){
tagdown2(p);
}
if(tr[p].l >= dl && tr[p].r <= dr){
tag1[p] = k;
tr[p].dat = k;
return;
}
update1(ls(p), dl, dr, k);
update1(rs(p), dl, dr, k);
pushup(p);
return;
}
void update2(int p, int dl, int dr, int k){
if(tr[p].l > dr || tr[p].r < dl){
return;
}
if(tag1[p] != -1){
tagdown1(p);
}
if(tag2[p] != 0){
tagdown2(p);
}
if(tr[p].l >= dl && tr[p].r <= dr){
tag2[p] += k;
tr[p].dat += k;
return;
}
update2(ls(p), dl, dr, k);
update2(rs(p), dl, dr, k);
pushup(p);
return;
}
int query(int p, int dl, int dr){
if(tr[p].l > dr || tr[p].r < dl){
return 0;
}
if(tag1[p] != -1){
tagdown1(p);
}
if(tag2[p] != 0){
tagdown2(p);
}
if(tr[p].l >= dl && tr[p].r <= dr){
return tr[p].dat;
}
int ret = std::max(query(ls(p), dl, dr), query(rs(p), dl, dr));
pushup(p);
return ret;
}
void _cover(int x, int y, int z){
while(tp[x] != tp[y]){
if(dep[tp[x]] < dep[tp[y]]){
std::swap(x, y);
}
update1(1, id[tp[x]], id[x], z);
x = fa[tp[x]];
}
if(dep[x] < dep[y]){
std::swap(x, y);
}
if(x != y){
update1(1, id[y] + 1, id[x], z);
}
return;
}
void _add(int x, int y, int z){
while(tp[x] != tp[y]){
if(dep[tp[x]] < dep[tp[y]]){
std::swap(x, y);
}
update2(1, id[tp[x]], id[x], z);
x = fa[tp[x]];
}
if(dep[x] < dep[y]){
std::swap(x, y);
}
if(x != y){
update2(1, id[y] + 1, id[x], z);
}
return;
}
void _query(int x, int y){
int ans = 0;
while(tp[x] != tp[y]){
if(dep[tp[x]] < dep[tp[y]]){
std::swap(x, y);
}
ans = std::max(ans, query(1, id[tp[x]], id[x]));
x = fa[tp[x]];
}
if(dep[x] < dep[y]){
std::swap(x, y);
}
if(x != y){
ans = std::max(ans, query(1, id[y] + 1, id[x]));
}
std::cout << ans << "\n";
return;
}
int main(){
std::cin >> n;
memset(tag1, -1, sizeof(tag1));
for(int i = 1; i < n; ++ i){
std::cin >> u[i] >> v[i] >> tmp[i];
mp[u[i]].push_back(v[i]);
mp[v[i]].push_back(u[i]);
}
get_info(1, 0);
for(int i = 1; i < n; ++ i){
if(dep[u[i]] < dep[v[i]]){
ww[v[i]] = tmp[i];
}
else{
ww[u[i]] = tmp[i];
}
}
get_tp(1, 1);
build(1, 1, n);
while(std::cin >> s){
if(s == "Stop"){
break;
}
if(s == "Change"){
int x, y;
std::cin >> x >> y;
if(dep[u[x]] < dep[v[x]]){
update1(1, id[v[x]], id[v[x]], y);
}
else{
update1(1, id[u[x]], id[u[x]], y);
}
}
if(s == "Cover"){
int x, y, z;
std::cin >> x >> y >> z;
_cover(x, y, z);
}
if(s == "Add"){
int x, y, z;
std::cin >> x >> y >> z;
_add(x, y, z);
}
if(s == "Max"){
int x, y;
std::cin >> x >> y;
_query(x, y);
}
}
return 0;
}