zlx517 @ 2020-09-12 10:26:06
RT
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1000010;
int n,m,r,p;
int wt[maxn],head[maxn],deep[maxn],weight[maxn],
id[maxn],wson[maxn],fa[maxn],val[maxn],top[maxn];
int tot,cnt,res;
struct edge{
int next,to,from,w,bel;
}e[maxn],ed[maxn];
struct segTree{
int l,r,sum,tag;
}st[maxn];
//加边
void adde(int a,int b){
e[++tot].to = b;
e[tot].next = head[a];
e[tot].from = a;
head[a] = tot;
e[++tot].to = a;
e[tot].next = head[b];
e[tot].from = b;
head[b] = tot;
}
void dfs1(int x,int f,int dep)
{
fa[x] = f;
deep[x] = dep;
weight[x] = 1;
int maxx = -1;
for(int i = head[x]; i; i = e[i].next)
{
int y = e[i].to;
if(y == f) continue;
dfs1(y,x,dep + 1);
weight[x] += weight[y];
if(weight[y] > maxx)
{
maxx = weight[y];
wson[x] = y;
}
}
return ;
}
void dfs2(int x,int topf)
{
id[x] = ++cnt;
wt[cnt] = val[x];
top[x] = topf;
if(!wson[x]) return ;
dfs2(wson[x],topf);
for(int i = head[x]; i; i = e[i].next)
{
int y = e[i].to;
if(!id[y]) dfs2(y,y);
}
return ;
}
void build(int now,int l,int r)
{
st[now].l = l;
st[now].r = r;
if(l == r)
{
st[now].sum = wt[l];
return ;
}
int mid = (l + r) / 2;
build(now * 2,l,mid);
build(now * 2 + 1,mid + 1,r);
st[now].sum = max(st[now * 2].sum,st[now * 2 + 1].sum);
return ;
}
void spread(int now)
{
if(!st[now].tag) return ;
int ls = now * 2,rs = now * 2 + 1;
st[ls].sum += st[now].tag * (st[ls].r - st[ls].l + 1);
st[rs].sum += st[now].tag * (st[rs].r - st[rs].l + 1);
st[ls].tag += st[now].tag;
st[rs].tag += st[now].tag;
st[now].tag = 0;
return ;
}
void add(int now,int l,int r,int k)
{
if(l <= st[now].l && r >= st[now].r)
{
st[now].sum += k * (st[now].r - st[now].l + 1);
st[now].tag += k;
return ;
}
spread(now);
int mid = (st[now].l + st[now].r) / 2;
if(l <= mid) add(now * 2,l,r,k);
if(r > mid) add(now * 2 + 1,l,r,k);
st[now].sum = max(st[now * 2].sum,st[now * 2 + 1].sum);
return ;
}
int query(int now,int l,int r)
{
if(l <= st[now].l && r >= st[now].r) return st[now].sum;
spread(now);
int ans = 0;
int mid = (st[now].l + st[now].r) / 2;
if(l <= mid) ans = max(ans,query(now * 2,l,r));
if(r > mid) ans = max(ans,query(now * 2 + 1,l,r));
return ans;
}
int qrange(int x,int y)
{
int ans = 0;
while(top[x] != top[y])
{
if(deep[top[x]] < deep[top[y]]) swap(x,y);
ans = max(ans,query(1,id[top[x]],id[x]));
x = fa[top[x]];
}
if(deep[x] > deep[y]) swap(x,y);
ans = max(ans,query(1,id[x] + 1,id[y]));
return ans;
}
void updrange(int x,int y,int k)
{
while(top[x] != top[y])
{
if(deep[top[x]] < deep[top[y]]) swap(x,y);
add(1,id[top[x]],id[x],k);
x = fa[top[x]];
}
if(deep[x] > deep[y]) swap(x,y);
add(1,id[x] + 1,id[y],k);
}
signed main()
{
scanf("%lld",&n);
for(int i = 1; i < n; i++)
{
int x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
adde(x,y);
ed[i].from = x,ed[i].to = y,ed[i].w = z;
}
dfs1(1,0,1);
for(int i = 1; i < n; i++)
{
int x = ed[i].from,y = ed[i].to;
if(deep[x] < deep[y]) val[y] = ed[i].w,ed[i].bel = y;
else val[x] = ed[i].w,ed[i].bel = x;
}
dfs2(1,1);
build(1,1,n);
while(1)
{
string op;
cin >> op;
if(op == "DONE") break;
if(op == "QUERY")
{
int x,y;
scanf("%lld%lld",&x,&y);
printf("%lld\n",qrange(x,y));
}
if(op == "CHANGE")
{
int x,y;
scanf("%lld%lld",&x,&y);
int pp = ed[x].bel;
add(1,id[pp],id[pp],y - val[pp]);
//updrange(x,x,y - val[x]);
}
}
return 0;
}
by Velix @ 2020-09-12 10:28:55
用户名危
by zhanghzqwq @ 2020-09-12 10:36:08
@大沙壁 树剖就慢慢调吧(