思路:树链剖分的裸题了
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn = 50000+100;
int siz[maxn],fa[maxn],son[maxn],dep[maxn],top[maxn],id[maxn];
int tot;
int val[maxn];
vector<int>e[maxn];
int n,m;
struct Node
{
int u,v;
LL val;
}nodes[maxn];
LL sum[maxn<<2];
#define lson i*2,l,m
#define rson i*2+1,m+1,r
void push_up(int i)
{
sum[i] = sum[i*2] + sum[i*2+1];
}
void build(int i,int l,int r)
{
if(l==r)
{
sum[i]=val[l];
return;
}
int m = (l+r)>>1;
build(lson);
build(rson);
push_up(i);
}
LL query(int ql,int qr,int i,int l,int r)
{
if(ql <= l && qr>=r)
return sum[i];
int m = (l+r)>>1;
LL ans = 0;
if (ql <= m)
ans+=query(ql,qr,lson);
if (m<qr)
ans+=query(ql,qr,rson);
return ans;
}
void update(int id,int val,int i,int l,int r)
{
if(l==r)
{
sum[i]=val;
return;
}
int m = (l+r)>>1;
if(id <=m)
update(id,val,lson);
else
update(id,val,rson);
push_up(i);
}
void dfs1(int u,int f,int d)
{
siz[u]=1;
son[u]=0;
fa[u]=f;
dep[u]=d;
for(int i = 0;i<e[u].size();i++)
{
int v = e[u][i];
if(v==f)
continue;
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(siz[son[u]] < siz[v])
son[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp;
id[u]=++tot;
if(son[u])
dfs2(son[u],tp);
for(int i = 0;i<e[u].size();i++)
{
int v= e[u][i];
if(v==fa[u] || v == son[u])
continue;
dfs2(v,v);
}
}
LL Yougth(int u,int v)
{
int tp1 = top[u],tp2 = top[v];
LL ans = 0;
while(tp1!=tp2)
{
if (dep[tp1] < dep[tp2])
{
swap(tp1,tp2);
swap(u,v);
}
ans +=query(id[tp1],id[u],1,1,tot);
u = fa[tp1];
tp1 = top[u];
}
if(u==v)
return ans;
if(dep[u] > dep[v])
swap(u,v);
ans += query(id[son[u]],id[v],1,1,tot);
return ans;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i = 0;i<=n;i++)
e[i].clear();
for(int i = 1;i<n;i++)
{
scanf("%d%d%lld",&nodes[i].u,&nodes[i].v,&nodes[i].val);
e[nodes[i].u].push_back(nodes[i].v);
e[nodes[i].v].push_back(nodes[i].u);
}
tot = 0;
dfs1(1,0,1);
dfs2(1,1);
for(int i = 1;i<n;i++)
{
if (dep[nodes[i].u] < dep[nodes[i].v])
swap(nodes[i].u,nodes[i].v);
val[id[nodes[i].u]] = nodes[i].val;
}
build(1,1,tot);
while(m--)
{
int op;
scanf("%d",&op);
if(op==1)
{
int uu,vv;
scanf("%d%d",&uu,&vv);
printf("%lld\n",Yougth(uu,vv));
}
else
{
int uu;
LL v;
scanf("%d%lld",&uu,&v);
update(id[nodes[uu].u],v,1,1,tot);
}
}
}
}