树剖的裸题,中文题面所以就不多解释了,当然操作二,就是简单的求过路费之和,因为路径唯一,他的那个最少过路费我也是醉了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = 50000+10;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct Point{
int x,y,val;
}point[maxn];
int head[maxn],edge_cnt,tot,value[maxn];
struct Edge{
int to,next;
}edge[maxn<<1];
inline void ADD(int u,int v){
edge[edge_cnt].to = v;
edge[edge_cnt].next = head[u];
head[u] = edge_cnt++;
}
int N,M;
int size[maxn],son[maxn],deep[maxn],fa[maxn];
void dfs1(int now,int father,int Deep){
fa[now] = father;
size[now] = 1;
deep[now] = Deep;
son[now] = 0;
for(int i = head[now]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v != father){
dfs1(v,now,Deep+1);
size[now] += size[v];
if(size[son[now]] < size[v])
son[now] = v;
}
}
}
int ID[maxn],Rank[maxn],top[maxn];
void dfs2(int now,int Top){
top[now] = Top;
ID[now] = ++tot;
Rank[ID[now]] = now;
if(son[now])
dfs2(son[now],Top);
for(int i = head[now]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v != fa[now] && v != son[now]){
dfs2(v,v);
}
}
}
struct Info{
int l,r,sum;
};
#define MID int Mid = (tree[now].l+tree[now].r)>>1
struct SGT{
Info tree[maxn<<2];
inline void pushUp(int now){
tree[now].sum = tree[now<<1].sum+tree[now<<1|1].sum;
}
void build(int now,int l,int r){
tree[now].l = l;
tree[now].r = r;
if(l == r){
tree[now].sum = value[Rank[l]];
return;
}
int Mid = (l+r)>>1;
build(now<<1,l,Mid);
build(now<<1|1,Mid+1,r);
pushUp(now);
}
inline void update(int now,int idx,int val){
if(tree[now].l == tree[now].r){
tree[now].sum = val;
return;
}
MID;
if(idx <= Mid)
update(now<<1,idx,val);
else
update(now<<1|1,idx,val);
pushUp(now);
}
inline int query(int now,int l,int r){
if(l <= tree[now].l && tree[now].r <= r)
return tree[now].sum;
MID;
int ans = 0;
if(l <= Mid)
ans += query(now<<1,l,r);
if(Mid < r)
ans += query(now<<1|1,l,r);
return ans;
}
};
SGT sgt;
int work(int u,int v){
int ans = 0;
int tpu = top[u];
int tpv = top[v];
while(tpu != tpv){
if(deep[tpu] < deep[tpv]){
swap(u,v);
swap(tpu,tpv);
}
ans += sgt.query(1,ID[tpu],ID[u]);
u = fa[tpu];
tpu = top[u];
}
if(u == v)return ans;
if(deep[u] > deep[v])
swap(u,v);
ans += sgt.query(1,ID[son[u]],ID[v]);
return ans;
}
int main(){
while(~scanf("%d %d",&N,&M)){
memset(head,-1,sizeof(head));
edge_cnt = tot = 0;
for(int i = 1; i < N; i++){
point[i].x = read();
point[i].y = read();
point[i].val = read();
ADD(point[i].x,point[i].y);
ADD(point[i].y,point[i].x);
}
dfs1(1,0,0);
dfs2(1,1);
value[1] = 0;
for(int i = 1; i < N; i++){
if(deep[point[i].x] < deep[point[i].y])
swap(point[i].x,point[i].y);
value[point[i].x] = point[i].val;
}
sgt.build(1,1,N);
int op,u,v;
while(M--){
op = read();
u = read();
v = read();
if(!op)
sgt.update(1,ID[point[u].x],v);
else
printf("%d\n",work(u,v));
}
}
return 0;
}