n个点,n-1条边,m次查询。
1 a b 代表查询 a点到b点路径权值和。
0 a b代表把第a条边权值更新为b
单点查询,区间更新,树剖裸题。
树剖代码量太大,写错一个变量可能就要就要查半天注意用long long
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stack>
#include <queue>
using namespace std;
/*
0 a b,表示更新第a条路的过路费为b,
1 <= a <= n-1 ; 二. 1 a b , 表示询问a到b最少要花多少过路费。*/
#define maxn 100010
typedef int ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
int n,m;
struct node{
int u,v,val;
}e[maxn<<2];
struct arr{
int to,val,next;
}V[maxn*10];
int head[maxn];
int topw,num,id[maxn],val[maxn],top[maxn],dep[maxn],fa[maxn],son[maxn],size[maxn];
void add(int u,int v,int val)
{
V[num].to=v;V[num].val=val;V[num].next=head[u];head[u]=num++;
}
void dfs_1(int u,int f,int d)
{
dep[u]=d;
size[u]=1;
fa[u]=f;
son[u]=0;
for(int i=head[u];~i;i=V[i].next)
{
int v=V[i].to;
if(v==f)continue;
dfs_1(v,u,d+1);
size[u]+=size[v];
if(size[son[u]]<size[v]) son[u]=v;
}
}
void dfs_2(int u,int tp)
{
top[u]=tp;
id[u]=++topw;
if(son[u]) dfs_2(son[u],tp);
for(int i=head[u];~i;i=V[i].next)
{
int v=V[i].to;
if(v==son[u]||v==fa[u]) continue;
dfs_2(v,v);
}
}
struct Tree{
int l,r,val;
}tree[maxn<<2];
void push_up(int rt)
{
tree[rt].val=tree[rt<<1].val+tree[rt<<1|1].val;
}
void build(int l,int r,int rt)
{
tree[rt].r=r;tree[rt].l=l;
if(l==r)
{
tree[rt].val=val[l];
return ;
}
int mid=(tree[rt].l+tree[rt].r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
push_up(rt);
}
long long query(int L,int R,int rt)
{
int l=tree[rt].l,r=tree[rt].r;
if(L<=l&&R>=r) return tree[rt].val;
int mid=(l+r)>>1;
if(R<=mid)
return query(L,R,rt<<1);
else if(L>mid)
return query(L,R,rt<<1|1);
else return query(L,mid,rt<<1)+query(mid+1,R,rt<<1|1);
}
long long change(int u,int v,int rt)
{
long long ans=0;
int tp1=top[u],tp2=top[v];
while(tp1!=tp2)
{
if(dep[tp1]<dep[tp2])
{
swap(tp1,tp2);swap(u,v);
}
ans+=query(id[tp1],id[u],1);
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);//*********************
return ans;
}
void update(int x,int y,int rt)
{
int l=tree[rt].l,r=tree[rt].r;
if(l==r)
{
tree[rt].val=y;return ;
}
int mid=(l+r)>>1;
if(x<=mid) update(x,y,rt<<1);
else update(x,y,rt<<1|1);
push_up(rt);
return ;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-1,sizeof(head));
topw=0;num=0;
for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
e[i].u=a,e[i].v=b,e[i].val=c;
}
dfs_1(1,0,1);
dfs_2(1,1);
for(int i=1;i<n;i++)
{
int x=e[i].u,y=e[i].v;
if(dep[x]<dep[y])
{
swap(e[i].u,e[i].v);
swap(x,y);
}
val[id[x]]=e[i].val;
}
build(1,topw,1);
while(m--)
{
int a,b,c;scanf("%d",&a);
if(a==1)
{
scanf("%d%d",&a,&b);
printf("%lld\n",change(a,b,1));
}
else
{
int x,y;scanf("%d%d",&x,&y);
update(id[e[x].u],y,1);
}
}
}
return 0;
}