#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int NN=210000;
int n,en,c[NN],head[NN];
struct Edge{
int v,w,next;
Edge() {}
Edge(int _v,int _w,int _next): v(_v),w(_w),next(_next) {}
} e[NN];
int index,bn,b[NN],f[NN],at[NN],fa[NN],num[NN],ctr[NN],dis[NN];
void dfs(int u)
{
int tmp=++index;
num[u]=index;
b[++bn]=tmp; f[tmp]=u; at[u]=bn;
for (int i=head[u]; i!=-1; i=e[i].next)
{
int v=e[i].v;
if (fa[u]==v) continue;
dis[v]=dis[u]+e[i].w;
fa[v]=u;
dfs(v);
b[++bn]=tmp;
}
ctr[u]=index;
}
int dp[NN][30];
inline void RMQ_init(int n)
{
for (int i=1; i<=n; i++) dp[i][0]=b[i];
int m=floor(log(n*1.0)/log(2.0));
for (int j=1; j<=m; j++)
for (int i=1; i<=n-(1<<j)+1; i++)
dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
inline int RMQ(int l,int r)
{
int k=floor(log(r-l+1)/log(2.0));
return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
inline int LCA(int a,int b)
{
if (at[a]>at[b]) swap(a,b);
return f[RMQ(at[a],at[b])];
}
inline int lowbit(int x)
{
return x&(-x);
}
inline void update(int x,int w)
{
if (x==0) return;
while (x<=n)
{
c[x]+=w;
x+=lowbit(x);
}
}
inline int get_sum(int x)
{
int ret=0;
while (x)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
inline int get(int x)
{
return get_sum(num[x]);
}
int U[NN],V[NN],W[NN];
int main()
{
int i,q,s,t,x,u,v,w,ans;
while (~scanf("%d%d%d",&n,&q,&s))
{
en=0;
for (i=1; i<=n; i++) head[i]=-1;
for (i=1; i<n; i++)
{
scanf("%d%d%d",&u,&v,&w);
e[en]=Edge(v,w,head[u]); head[u]=en++;
e[en]=Edge(u,w,head[v]); head[v]=en++;
U[i]=u; V[i]=v; W[i]=w;
}
fa[1]=num[0]=dis[1]=index=bn=0;
dfs(1);
RMQ_init(bn);
for (i=1; i<=q; i++)
{
scanf("%d",&w);
if (w)
{
scanf("%d%d",&x,&v);
if (fa[U[x]]==V[x]) u=U[x];
else u=V[x];
update(num[u],v-W[x]);
update(ctr[u]+1,W[x]-v);
W[x]=v;
}
else
{
scanf("%d",&t);
x=LCA(s,t);
ans=dis[s]+get(s)+dis[t]+get(t)-2*(dis[x]+get(x));
printf("%d\n",ans);
s=t;
}
}
}
return 0;
}
POJ2763-LCA在線算法+樹狀數組
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.