地址
树链剖分
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf 0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",&n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define N 100005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
using namespace std;
typedef long long ll;
typedef double db;
const ll mod=1e9+7;
struct edge
{
int d,next;
edge():next(-1){}
}e[2*N];
struct node
{
int st,go,t;
node(){}
node(int s,int x,int y):st(s),go(x),t(y){}
}num[N];
int f[N],d[N],siz[N],son[N],rk[N],top[N],id[N],a[N],n;
int t[3*N],add[3*N],head[N];
int which=1;
void add1(int s,int d)
{
e[which].d=d;
e[which].next=head[s];
head[s]=which++;
}
void down(int r,int st,int ed)
{
if(add[r])
{
add[r<<1]=add[r];
add[r<<1|1]=add[r];
int mid=(st+ed)>>1;
t[r<<1]=add[r]*(mid-st+1);
t[r<<1|1]=add[r]*(ed-mid);
add[r]=0;
}
}
void build(int r,int st,int ed)
{
if(st==ed) t[r]=a[rk[st]];
else
{
int mid=(st+ed)>>1;
build(r<<1,st,mid);
build(r<<1|1,mid+1,ed);
t[r]=t[r<<1]+t[r<<1|1];
}
}
void update(int r,int st,int ed,int x,int y,int z)
{
if(st>y||ed<x) return ;
if(st>=x&&ed<=y)
{
add[r]=z;
t[r]=z*(ed-st+1);
return ;
}
down(r,st,ed);
int mid=(st+ed)>>1;
update(r<<1|1,mid+1,ed,x,y,z);
update(r<<1,st,mid,x,y,z);
t[r]=t[r<<1]+t[r<<1|1];
}
int findm(int r,int st,int ed,int x,int y)
{
if(st>y||ed<x) return 0;
if(st>=x&&ed<=y) return t[r];
down(r,st,ed);
int mid=(st+ed)>>1;
return (findm(r<<1,st,mid,x,y)+findm(r<<1|1,mid+1,ed,x,y));
}
void dfs1(int x,int fa,int dep)
{
f[x]=fa;
siz[x]=1;
d[x]=dep;
for(int i=head[x];i!=-1;i=e[i].next)
{
int to=e[i].d;
if(to!=fa)
{
dfs1(to,x,dep+1);
siz[x]+=siz[to];
if(siz[to]>siz[son[x]]) son[x]=to;
}
}
}
int cnt;
void dfs2(int x,int t)
{
top[x]=t;
id[x]=++cnt;
rk[cnt]=x;
if(!son[x]) return ;
dfs2(son[x],t);
for(int i=head[x];i!=-1;i=e[i].next)
{
int to=e[i].d;
if(to!=son[x]&&to!=f[x]) dfs2(to,to);
}
}
int sum(int x,int y)
{
int ans=0,fx=top[x],fy=top[y];
while(fx!=fy)
{
if(d[fx]>d[fy])
{
ans+=findm(1,1,n,id[fx],id[x]);
x=f[fx];
}
else
{
ans+=findm(1,1,n,id[fy],id[y]);
y=f[fy];
}
fx=top[x];
fy=top[y];
}
if(x==y) return ans;
if(id[x]<=id[y]) ans+=findm(1,1,n,id[son[x]],id[y]);
else ans+=findm(1,1,n,id[son[y]],id[x]);
return ans;
}
void updateson(int x,int y,int c)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(d[fx]>=d[fy])
{
update(1,1,n,id[fx],id[x],c);
x=f[fx];
}
else
{
update(1,1,n,id[fy],id[y],c);
y=f[fy];
}
fx=top[x];
fy=top[y];
}
if(id[x]<=id[y]) update(1,1,n,id[x],id[y],c);
else update(1,1,n,id[y],id[x],c);
}
int main()
{
int m,r;
mem(head,-1);
sddd(n,m,r);
fup(i,1,n-1)
{
int x,y,z;
sddd(num[i].st,num[i].go,num[i].t);
x=num[i].st,y=num[i].go;
add1(x,y);
add1(y,x);
}
dfs1(1,0,1);
dfs2(1,1);
fup(i,1,n-1)
{
int x=num[i].st,y=num[i].go;
if(d[x]<d[y]) swap(x,y),swap(num[i].st,num[i].go);
a[x]=num[i].t;
}
build(1,1,n);
while(m--)
{
int op,x,y,z;
sd(op);
if(op==0)
{
sd(x);
pf(sum(r,x));
r=x;
}
else
{
sdd(x,z);
x=num[x].st;
update(1,1,n,id[x],id[x],z);
}
}
return 0;
}
LCA加树状数组
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf 0x7fffffff
#define linf 0x7fffffffffffffff
#define fil(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define debug printf("!!\n");
#define N 100005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
using namespace std;
typedef long long ll;
typedef double db;
int n,s;
struct node
{
int go,t;
node(int a,int b)
{
go=a;
t=b;
}
};
struct node1
{
int x,y,z;
}num[N];
int fa[N],deep[N],dp[N][20],dis[N],st[N],ed[N],change[N];
vector<node> q[N];
int id;
void dfs(int x,int dep)
{
st[x]=++id;
deep[x]=dep;
dp[x][0]=fa[x];
for(int i=1;(1<<i)<deep[x];i++)
dp[x][i]=dp[dp[x][i-1]][i-1];
for(int i=0;i<q[x].size();i++)
{
node tp=q[x][i];
if(tp.go!=fa[x])
{
dis[tp.go]=dis[x]+tp.t;
fa[tp.go]=x;
dfs(tp.go,dep+1);
}
}
ed[x]=id+1;
}
int lca(int a,int b)
{
if(deep[a]>deep[b]) swap(a,b);
int k=deep[b]-deep[a];
for(int i=0;i<=19;i++)
if((1<<i)&k) b=dp[b][i];
for(int i=19;i>=0;i--)
if(dp[a][i]!=dp[b][i]) a=dp[a][i],b=dp[b][i];
if(a==b) return a;
return dp[a][0];
}
void add(int i,int x)
{
while(i<=n+1)
{
change[i]+=x;
i+=lowbit(i);
}
}
int cal(int i)
{
int ans=0;
while(i>0)
{
ans+=change[i];
i-=lowbit(i);
}
return ans;
}
void solve()
{
int tt,m,s;
sddd(n,m,s);
id=0;
fup(i,1,n-1)
{
int x,y,z;
sddd(x,y,z);
q[x].push_back(node(y,z));
q[y].push_back(node(x,z));
num[i].x=x;
num[i].y=y;
num[i].z=z;
}
dfs(s,1);
while(m--)
{
int x,y,f;
sd(f);
if(!f)
{
sd(x);
int clo=lca(s,x);
int res=cal(st[s])+cal(st[x])-2*cal(st[clo]);
pf(dis[x]+dis[s]-2*dis[clo]+res);
s=x;
}
else
{
sdd(x,y);
if(fa[num[x].x]==num[x].y) swap(num[x].x,num[x].y);
add(st[num[x].y],y-num[x].z);
add(ed[num[x].y],-y+num[x].z);
num[x].z=y;
}
}
}
int main()
{
int t=1;
while(t--)
{
solve();
}
return 0;
}