题意:给出树的边权 要求的操作是修改某条边的边权 然后询问是两个点之间的距离
解法:边权转点权啊 然后就去掉lca 这个操作真的太神 然后真的太轻松了 据说线段树也能写这题 大概是转成dfs序
边权怎么维护还没有想到
#include<queue>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define MAXN 111111
#define ls ch[rt][0]
#define rs ch[rt][1]
int ch[MAXN][2],fa[MAXN],sum[MAXN],val[MAXN],_rt[MAXN];
inline void up(int rt){sum[rt]=val[rt]+sum[ls]+sum[rs];}
inline void rot(int rt){
int f=fa[rt],side=ch[f][1]==rt,ll=ch[rt][!side];
fa[ll]=f,ch[f][side]=ll;
fa[rt]=fa[f];
if(_rt[f])_rt[rt]=1,_rt[f]=0;
else ch[fa[f]][ch[fa[f]][1]==f]=rt;
fa[f]=rt,ch[rt][!side]=f;
up(f),up(rt);
}
inline void splay(int rt){
while(!_rt[rt]){
int f=fa[rt],ff=fa[f];
if(_rt[f])rot(rt);
else if((ch[ff][1]==f)==(ch[f][1]==rt))rot(f),rot(rt);
else rot(rt),rot(rt);
}
}
inline int ace(int rt){
int y=0;
for(;rt;y=rt,rt=fa[rt]){
splay(rt);
_rt[rs]=1,rs=y;_rt[rs]=0;
up(rt);
}return y;
}
inline void lca(int &u,int &v){
ace(v),v=0;
while(u){
splay(u);
if(!fa[u])return ;
_rt[ch[u][1]]=1;ch[u][1]=v;_rt[v]=0;
up(u);v=u;
u=fa[u];
}
}
inline void change(int u,int k){
ace(u);val[u]=k;up(u);
}
inline void query(int u,int v){
lca(u,v);
printf("%d\n",sum[v]+sum[ch[u][1]]);
}
struct edge{
int v,next,val,idx;
}e[MAXN<<1];
int head[MAXN],tot,id[MAXN];
inline void add(int u,int v,int val,int index){
e[tot].v=v;e[tot].next=head[u];
e[tot].val=val;e[tot].idx=index;
head[u]=tot++;
}
inline void dfs(int u){
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(fa[v]!=0)continue;
fa[v]=u;
id[e[i].idx]=v;val[v]=e[i].val;
dfs(v);
}
}
inline void init(){tot=0;memset(head,-1,sizeof head);}
int u,v,w,n,m,op,a,b;
int main(){
while(~scanf("%d%d%d",&n,&m,&u)){
init();
for(int rt=0;rt<=n;++rt){
fa[rt]=ls=rs=0;_rt[rt]=1;
}
val[0]=sum[0]=0;
for(int i=1;i<n;++i){
scanf("%d%d%d",&a,&b,&w);
add(b,a,w,i);add(a,b,w,i);
}fa[1]=-1;dfs(1);fa[1]=0;
// for(int i=1;i<=n;++i)printf("%d ",val[i]);
while(m--){
scanf("%d",&op);
if(op==1){scanf("%d%d",&a,&v);change(id[a],v);}
else{
scanf("%d",&v);
// printf("%d %d\n",u,v);
query(u,v);
u=v;
}
}
}
return 0;
}