#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
using namespace std;
const int Max=50005;
__int64 val[Max];
struct SegmentTree
{
__int64 sum[Max<<2];
int L,R;
void Build(int idx,int left,int right)
{
if(left == right)
{
sum[idx]=val[left];
return;
}
int mid=(left+right)>>1;
Build(idx<<1,left,mid);
Build(idx<<1|1,mid+1,right);
sum[idx]=sum[idx<<1]+sum[idx<<1|1];
}
void Update(int idx,int left,int right,int pos,int data)
{
if(left == right)
{
sum[idx]=data;
return;
}
int mid=(left+right)>>1;
if(pos<=mid) Update(idx<<1,left,mid,pos,data);
else Update(idx<<1|1,mid+1,right,pos,data);
sum[idx]=sum[idx<<1]+sum[idx<<1|1];
}
__int64 Query(int idx,int left,int right)
{
if(L<=left && right<=R)
return sum[idx];
int mid=(left+right)>>1;
__int64 ans=0;
if(L<=mid) ans+=Query(idx<<1,left,mid);
if(mid<R) ans+=Query(idx<<1|1,mid+1,right);
return ans;
}
}tree;
struct Edge
{
int v,next,w;
}edge[Max<<1];
int f[Max],fa[Max],son[Max],top[Max],tot[Max];
int pos[Max],depth[Max],size;
void Add(int u,int v,int w,int& cnt)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=f[u];
f[u]=cnt++;
edge[cnt].v=u;
edge[cnt].w=w;
edge[cnt].next=f[v];
f[v]=cnt++;
}
void Init()
{
memset(f,-1,sizeof(f));
fa[1]=top[1]=1;
depth[1]=size=0;
}
//tot,fa,son,depth
void Dfs1(int cur)
{
tot[cur]=1;
son[cur]=0;
int i,v,maxv=-1;
for(i=f[cur];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(v!=fa[cur])
{
fa[v]=cur;
depth[v]=depth[cur]+1;
Dfs1(v);
tot[cur]+=tot[v];
if(tot[v]>maxv) maxv=tot[v],son[cur]=v;
}
}
}
//pos,top
void Dfs2(int cur)
{
int v=son[cur],i;
pos[cur]=++size;
if(v)
{
top[v]=top[cur];
Dfs2(v);
}
for(i=f[cur];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(v==fa[cur]) val[pos[cur]]=edge[i].w;
else if(v!=son[cur])
{
top[v]=v;
Dfs2(v);
}
}
}
void Update(int idx,int data)
{
int i=idx*2-1;
int u=edge[i].v,v=edge[i^1].v;
if(depth[u]<depth[v]) swap(u,v);
tree.Update(1,2,size,pos[u],data);
}
__int64 Query(int u,int v)
{
__int64 ans=0;
int topu=top[u];
int topv=top[v];
while(topu!=topv)
{
if(depth[topu]<depth[topv])
swap(u,v),swap(topu,topv);
tree.L=pos[topu],tree.R=pos[u];
ans+=tree.Query(1,2,size);
u=fa[topu];
topu=top[u];
}
if(u==v) return ans;
if(depth[v]<depth[u]) swap(u,v);
tree.L=pos[son[u]];
tree.R=pos[v];
ans+=tree.Query(1,2,size);
return ans;
}
int main()
{
//freopen("test.txt","r",stdin);
int N,M,i,u,v,w,cnt;
while(~scanf("%d %d",&N,&M))
{
Init();
for(i=1,cnt=0;i<N;++i)
{
scanf("%d %d %d",&u,&v,&w);
Add(u,v,w,cnt);
}
Dfs1(1);
Dfs2(1);
tree.Build(1,2,N);
while(M--)
{
scanf("%d %d %d",&i,&u,&v);
if(i) printf("%I64d\n",Query(u,v));
else Update(u,v);
}
}
return 0;
}
FOJ2082 过路费
最新推荐文章于 2018-04-14 23:42:11 发布