只是一个仅仅6KB的代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = (int)1e5+10;
int N,Q,k,tot=0;
double xsum,xmin,xmax,count;
int head[maxn],dep[maxn],fa[maxn],hv[maxn],anc[maxn],size[maxn],id[maxn],L[maxn],R[maxn];
struct node{int v,next;}e[2*maxn];
struct tree{
int l,r;
double sum,min,max,col,re;
}t[4*maxn];
void adde(int u,int v){
e[k].v=v; e[k].next=head[u]; head[u]=k++;
}
void pre_dfs(int u,int f,int dis){
dep[u]=dis; fa[u]=f; hv[u]=-1; size[u]=1;
int t=0;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(v==f)continue;
pre_dfs(v,u,dis+1);
size[u]+=size[v];
if(size[v]>t){
t=size[v]; hv[u]=v;
}
}
}
void dfs(int u,int x){
anc[u]=x; id[u]=++tot; L[u]=tot;
if(hv[u]!=-1)dfs(hv[u],x);
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(v==fa[u] || v==hv[u])continue;
dfs(v,v);
}
R[u]=tot;
}
void pushup(int x){
t[x].sum=t[x<<1].sum+t[x<<1|1].sum;
t[x].min=min(t[x<<1].min,t[x<<1|1].min);
t[x].max=max(t[x<<1].max,t[x<<1|1].max);
}
void pushdown(int x){
if(t[x].col==1){//col=1表示该次为变为相同的操作
t[x<<1].min=t[x<<1].max=t[x<<1].re=t[x].re;
t[x<<1].sum=(t[x<<1].r-t[x<<1].l+1)*t[x].re;
t[x<<1|1].min=t[x<<1|1].max=t[x<<1|1].re=t[x].re;
t[x<<1|1].sum=(t[x<<1|1].r-t[x<<1|1].l+1)*t[x].re;
t[x<<1].col=t[x<<1|1].col=1;
t[x].col=-1; t[x].re=0;
}
if(t[x].col==2){//col=2表示该次是增加的操作
t[x<<1].min+=t[x].re; t[x<<1].max+=t[x].re; t[x<<1].re+=t[x].re;
t[x<<1].sum+=(t[x<<1].r-t[x<<1].l+1)*t[x].re;
t[x<<1|1].min+=t[x].re; t[x<<1|1].max+=t[x].re; t[x<<1|1].re+=t[x].re;
t[x<<1|1].sum+=(t[x<<1|1].r-t[x<<1|1].l+1)*t[x].re;
if(t[x<<1].col!=1)t[x<<1].col=2;
if(t[x<<1|1].col!=1)t[x<<1|1].col=2;
//t[x<<1].col=t[x<<1|1].col=2;
t[x].col=-1; t[x].re=0;
}
}
void built(int x,int l,int r){
t[x].l=l; t[x].r=r;
if(l==r){
t[x].col=-1; t[x].re=0; t[x].sum=0; t[x].min=0; t[x].max=0; return ;
}
int mid=(l+r)>>1;
built(x<<1,l,mid); built(x<<1|1,mid+1,r);
}
void modify(int x,int l,int r,double v){//make them to be the same.
if(t[x].l>=l && t[x].r<=r){
t[x].min=t[x].max=v;
t[x].sum=v*(t[x].r-t[x].l+1);
t[x].re=v; t[x].col=1;
return ;
}
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(l<=mid)modify(x<<1,l,r,v);
if(r> mid)modify(x<<1|1,l,r,v);
pushup(x);
}
void improve(int x,int l,int r,double v){//add v to all nodes in this segment.
if(t[x].l>=l && t[x].r<=r){
t[x].sum+=(t[x].r-t[x].l+1)*v;
t[x].min+=v; t[x].max+=v;
t[x].re+=v;
if(t[x].col!=1)t[x].col=2;
return ;
}
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(l<=mid)improve(x<<1,l,r,v);
if(r> mid)improve(x<<1|1,l,r,v);
pushup(x);
}
void ask(int x,int l,int r){
if(t[x].l>=l && t[x].r<=r){
xsum+=t[x].sum; xmin=min(xmin,t[x].min); xmax=max(xmax,t[x].max);
count+=t[x].r-t[x].l+1; return ;
}
pushdown(x);
int mid=(t[x].l+t[x].r)>>1;
if(l<=mid)ask(x<<1,l,r);
if(r> mid)ask(x<<1|1,l,r);
pushup(x);
}
void change(int x,int y,double v,int op){//1->F, 2->N,3->C
int ux=anc[x],uy=anc[y];
while(ux!=uy){
if(dep[ux]>dep[uy]){
swap(x,y); swap(ux,uy);
}
if(op==1)modify(1,id[uy],id[y],v);
if(op==2)improve(1,id[uy],id[y],v);
if(op==3)ask(1,id[uy],id[y]);
y=fa[uy]; uy=anc[y];
}
if(dep[x]>dep[y])swap(x,y);
if(op==1)modify(1,id[x],id[y],v);
if(op==2)improve(1,id[x],id[y],v);
if(op==3)ask(1,id[x],id[y]);
}
int main(){
int T;
while(scanf("%d",&T)==1){
k=0;
memset(head,-1,sizeof(head));
scanf("%d%d",&N,&Q);
for(int i=1;i<N;i++){
int a,b; scanf("%d%d",&a,&b);
adde(a,b); adde(b,a);
}
pre_dfs(1,-1,0);
dfs(1,1);
built(1,1,tot);
char s[10];
for(int i=1;i<=Q;i++){
scanf("%s",s); int l=strlen(s);
int a,b; double v;
if(l==1){
if(s[0]=='F'){
scanf("%d%d",&a,&b);
xsum=0; xmin=10000000000000000; xmax=0; count=0;
change(a,b,0,3);
change(a,b,xsum/count,1);
}
else if(s[0]=='N'){
scanf("%d%d%lf",&a,&b,&v);
change(a,b,v,2);
}
else {
scanf("%d%d",&a,&b);
xsum=0; xmin=10000000000000000; xmax=0; count=0;
change(a,b,0,3);
printf("%lf %lf %lf\n",xmin,xmax,xsum);
}
}
else{
if(s[1]=='F'){
scanf("%d",&a);
xsum=0; xmin=10000000000000000; xmax=0; count=0;
ask(1,L[a],R[a]);
modify(1,L[a],R[a],xsum/count);
}
else if(s[1]=='N'){
scanf("%d%lf",&a,&v);
improve(1,L[a],R[a],v);
}
else {
scanf("%d",&a);
xsum=0; xmin=10000000000000000; xmax=0; count=0;
ask(1,L[a],R[a]);
printf("%lf %lf %lf\n",xmin,xmax,xsum);
}
}
}
}
return 0;
}