基于点
#include<iostream>
#include<cstdio>
using namespace std;
const int MAX_N=50100;
int size[MAX_N],wson[MAX_N],dfn[MAX_N],deep[MAX_N],pre[MAX_N],top[MAX_N],fa[MAX_N];
int head[MAX_N],Next[2*MAX_N],ver[2*MAX_N];
int tot,cnt;
struct node{
int l,r,sum,lazy;
}a[MAX_N*4];
int b[MAX_N];
void update(int k){
a[k].sum=a[k<<1].sum+a[k<<1|1].sum;
}
void build(int k,int l,int r){
a[k].l=l;a[k].r=r;a[k].lazy=0;
if(l==r){
a[k].sum=b[pre[l]];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(k);
}
void pushdown(int k){
if(a[k].lazy==0)
return;
a[k<<1].lazy+=a[k].lazy;
a[k<<1|1].lazy+=a[k].lazy;
a[k<<1].sum+=(a[k<<1].r-a[k<<1].l+1)*a[k].lazy;
a[k<<1|1].sum+=(a[k<<1|1].r-a[k<<1|1].l+1)*a[k].lazy;
a[k].lazy=0;
}
void changeS(int k,int l,int r,int y){
if(a[k].l>=l&&a[k].r<=r){
a[k].sum+=(a[k].r-a[k].l+1)*y;
a[k].lazy+=y;
return;
}
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
if(l<=mid)
changeS(k<<1,l,r,y);
if(r>mid)
changeS(k<<1|1,l,r,y);
update(k);
}
int query(int k,int l,int r){
if(a[k].l>=l&&a[k].r<=r)
return a[k].sum;
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
int x=0;
if(l<=mid)
x+=query(k<<1,l,r);
if(r>mid)
x+=query(k<<1|1,l,r);
return x;
}
void Add(int x,int y){
ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
}
void dfs1(int x,int fat){
size[x]=1;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fat)
continue;
deep[y]=deep[x]+1;
fa[y]=x;
dfs1(y,x);
size[x]+=size[y];
if(size[wson[x]]<size[y])
wson[x]=y;
}
}
void dfs2(int x,int tp){
dfn[x]=++cnt;
pre[cnt]=x;
top[x]=tp;
if(wson[x])
dfs2(wson[x],tp);
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y!=wson[x]&&y!=fa[x])
dfs2(y,y);
}
}
void modify(int x,int y,int d){//修改x到y路径上的值
while(top[x]!=top[y]){
if(dfn[top[x]]<dfn[top[y]])
swap(x,y);
changeS(1,dfn[top[x]],dfn[x],d);
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
changeS(1,dfn[x],dfn[y],d);
}
int Qsum(int x,int y){
int ret=0;
while(top[x]!=top[y]){
if(dfn[top[x]]<dfn[top[y]])
swap(x,y);
ret+=query(1,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
ret+=query(1,dfn[x],dfn[y]);
return ret;
}
int main(void){
int i,n,m,q,x,y,c1,c2,k;
while(scanf("%d%d%d",&n,&m,&q)!=EOF){
for(i=1;i<=n;i++){
head[i]=0;
deep[i]=0;
wson[i]=0;
}
tot=0;
cnt=0;
for(i=1;i<=n;i++){
scanf("%d",&b[i]);
}
for(i=0;i<m;i++){
scanf("%d%d",&x,&y);
Add(x,y);
Add(y,x);
}
deep[1]=1;
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
for(i=0;i<q;i++){
string s;
cin>>s;
if(s[0]=='I'){
scanf("%d%d%d",&c1,&c2,&k);
modify(c1,c2,k);
}
else if(s[0]=='D'){
scanf("%d%d%d",&c1,&c2,&k);
modify(c1,c2,-k);
}
else{
scanf("%d",&c1);
printf("%d\n",Qsum(c1,c1));
}
}
}
return 0;
}
基于边
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
const int MAX_N=10100;
int size[MAX_N],wson[MAX_N],dfn[MAX_N],deep[MAX_N],pre[MAX_N],top[MAX_N],fa[MAX_N];
int head[MAX_N],Next[2*MAX_N],ver[2*MAX_N],edge[2*MAX_N];
int dp[MAX_N][22];
int tt;
int tot,cnt;
struct node{
int l,r,lazy,maxl;
}a[MAX_N*4];
struct skt{
int u,v,w;
}ed[MAX_N];
int b[MAX_N];
inline void update(int k){
a[k].maxl=max(a[k<<1].maxl,a[k<<1|1].maxl);
}
inline void build(int k,int l,int r){
a[k].l=l;a[k].r=r;a[k].lazy=0;
if(l==r){
a[k].maxl=b[pre[l]];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(k);
}
inline void pushdown(int k){
if(a[k].lazy==0)
return;
a[k<<1].lazy=a[k<<1|1].lazy=a[k].lazy;
a[k<<1].maxl=a[k].lazy;
a[k<<1|1].maxl=a[k].lazy;
//a[k<<1].sum=(a[k<<1].r-a[k<<1].l+1)*a[k].lazy;
//a[k<<1|1].sum=(a[k<<1|1].r-a[k<<1|1].l+1)*a[k].lazy;
a[k].lazy=0;
}
inline void changeS(int k,int l,int r,int y){
if(a[k].l>=l&&a[k].r<=r){
//a[k].sum+=(a[k].r-a[k].l+1)*y;
a[k].maxl=y;
a[k].lazy=y;
return;
}
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
if(l<=mid)
changeS(k<<1,l,r,y);
if(r>mid)
changeS(k<<1|1,l,r,y);
update(k);
}
inline int query(int k,int l,int r){
if(a[k].l>=l&&a[k].r<=r)
return a[k].maxl;
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
int x=0;
if(l<=mid)
x=max(x,query(k<<1,l,r));
if(r>mid)
x=max(x,query(k<<1|1,l,r));
return x;
}
inline int LCA(int x,int y){
if(deep[x]>deep[y])
swap(x,y);
for(int i=tt;i>=0;i--)
if(deep[dp[y][i]]>=deep[x])
y=dp[y][i];
if(x==y)
return x;
for(int i=tt;i>=0;i--){
if(dp[x][i]!=dp[y][i]){
x=dp[x][i];
y=dp[y][i];
}
}
return dp[x][0];
}
inline void Add(int x,int y,int z){
ver[++tot]=y;edge[tot]=z;Next[tot]=head[x];head[x]=tot;
}
inline void dfs1(int x,int fat){
size[x]=1;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fat)
continue;
deep[y]=deep[x]+1;
dp[y][0]=x;
fa[y]=x;
b[y]=edge[i];
dfs1(y,x);
size[x]+=size[y];
if(size[wson[x]]<size[y])
wson[x]=y;
}
}
inline void dfs2(int x,int tp){
dfn[x]=++cnt;
pre[cnt]=x;
top[x]=tp;
if(wson[x])
dfs2(wson[x],tp);
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y!=wson[x]&&y!=fa[x])
dfs2(y,y);
}
}
inline void modify(int x,int y,int d){//修改x到y路径上的值
while(top[x]!=top[y]){
if(dfn[top[x]]<dfn[top[y]])
swap(x,y);
changeS(1,dfn[top[x]],dfn[x],d);
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
changeS(1,dfn[x],dfn[y],d);
}
inline int Qsum(int x,int y){
int ret=0;
while(top[x]!=top[y]){
if(dfn[top[x]]<dfn[top[y]])
swap(x,y);
ret=max(ret,query(1,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
ret=max(ret,query(1,dfn[x],dfn[y]));
return ret;
}
inline int fson(int x,int lca){
for(int i=tt;i>=0;i--){
if(deep[dp[x][i]]>deep[lca])
x=dp[x][i];
}
return x;
}
int main(void){
int T;
cin>>T;
int i,j,n,m,q,x,y,u,v,w;
while(T--){
scanf("%d",&n);
tt=(int)(log(n)/log(2))+1;
for(i=1;i<=n;i++){
head[i]=0;
deep[i]=0;
wson[i]=0;
fa[i]=0;
}
tot=0;
cnt=0;
for(i=1;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
ed[i].u=u;ed[i].v=v;ed[i].w=w;
Add(u,v,w);
Add(v,u,w);
}
deep[1]=1;
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
for(i=1;i<=tt;i++){
for(j=1;j<=n;j++){
dp[j][i]=dp[dp[j][i-1]][i-1];
}
}
char s[10];
while(scanf("%s",s)!=EOF){
if(s[0]=='C'){
scanf("%d%d",&x,&y);
u=ed[x].u;v=ed[x].v;w=ed[x].w;
ed[x].w=y;
if(fa[u]!=v)
swap(u,v);
modify(u,u,y);
}
else if(s[0]=='Q'){
scanf("%d%d",&x,&y);
int lca=LCA(x,y);
//cout<<lca<<" lca\n";
int ans=0;
if(x!=lca)
ans=max(ans,Qsum(fson(x,lca),x));
if(y!=lca)
ans=max(ans,Qsum(fson(y,lca),y));
printf("%d\n",ans);
}
else if(s[0]=='D')
break;
}
}
return 0;
}