。。。。。。。好长啊。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 50050 #define maxe 100500 #define inf 2000000000 using namespace std; int n,m,val[maxv],x,y,z,g[maxv],nume=1,fath[maxv],top[maxv],w[maxv],fw[maxv],son[maxv],size[maxv],dis[maxv],times=0; int tot=0,root,ls[maxv<<2],rs[maxv<<2],mn[maxv<<2],mx[maxv<<2],fr[maxv<<2],ba[maxv<<2],lazy[maxv<<2]; int r1,r2,r3; struct edge { int v,nxt; }e[maxe]; int read() { char ch;int data=0; while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9') { data=data*10+ch-'0'; ch=getchar(); } return data; } void addedge(int u,int v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void dfs1(int x) { size[x]=1;son[x]=0; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=fath[x]) { fath[v]=x;dis[v]=dis[x]+1; dfs1(v); size[x]+=size[v]; if (size[son[x]]<size[v]) son[x]=v; } } } void dfs2(int x,int father) { w[x]=++times;fw[times]=x;top[x]=father; if (son[x]) dfs2(son[x],father); for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if ((v!=fath[x]) && (v!=son[x])) dfs2(v,v); } } void reset() { r1=inf;r2=0;r3=0; } void pushup(int now) { mx[now]=max(mx[ls[now]],mx[rs[now]]); mn[now]=min(mn[ls[now]],mn[rs[now]]); fr[now]=max((mx[rs[now]]-mn[ls[now]]),max(fr[ls[now]],fr[rs[now]])); ba[now]=max((mx[ls[now]]-mn[rs[now]]),max(ba[ls[now]],ba[rs[now]])); } void pushdown(int now,int left,int right) { if (!lazy[now]) return; lazy[ls[now]]+=lazy[now];lazy[rs[now]]+=lazy[now]; mx[ls[now]]+=lazy[now];mx[rs[now]]+=lazy[now]; mn[ls[now]]+=lazy[now];mn[rs[now]]+=lazy[now]; lazy[now]=0; } void build(int &now,int left,int right) { now=++tot; if (left==right) {mn[now]=mx[now]=val[fw[left]];fr[now]=ba[now]=0;return;} int mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); pushup(now); } void ask(int now,int left,int right,int l,int r,int type) { pushdown(now,left,right); if ((left==l) && (right==r)) { if (type==1) r3=max(r3,mx[now]-r1);else r3=max(r3,r2-mn[now]); if (type==1) r3=max(r3,fr[now]);else r3=max(r3,ba[now]); r1=min(r1,mn[now]);r2=max(r2,mx[now]); return; } int mid=(left+right)>>1; if (r<=mid) ask(ls[now],left,mid,l,r,type); else if (l>=mid+1) ask(rs[now],mid+1,right,l,r,type); else { ask(ls[now],left,mid,l,mid,type); ask(rs[now],mid+1,right,mid+1,r,type); } } void modify(int now,int left,int right,int l,int r,int x) { pushdown(now,left,right); if ((left==l) && (right==r)) { lazy[now]+=x;mn[now]+=x;mx[now]+=x; return; } int mid=(left+right)>>1; if (r<=mid) modify(ls[now],left,mid,l,r,x); else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,x); else { modify(ls[now],left,mid,l,mid,x); modify(rs[now],mid+1,right,mid+1,r,x); } pushup(now); } int lca(int x,int y) { int f1=top[x],f2=top[y]; while (f1!=f2) { if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);} x=fath[f1];f1=top[x]; } if (dis[x]<dis[y]) return x;else return y; } void find_answer(int x,int y,int z) { int ans=0,t=lca(x,y),mn,mx; int f1=top[x],f2=top[y]; mn=inf;mx=0; while (f1!=top[t]) { reset();ask(root,1,n,w[f1],w[x],2); ans=max(ans,r2-mn);ans=max(ans,r3);mn=min(mn,r1); x=fath[f1];f1=top[x]; } reset();ask(root,1,n,w[t],w[x],2); ans=max(ans,r2-mn);ans=max(ans,r3);mn=min(mn,r1); while (f2!=top[t]) { reset();ask(root,1,n,w[f2],w[y],1); ans=max(ans,mx-r1);ans=max(ans,r3);mx=max(mx,r2); y=fath[f2];f2=top[y]; } reset();ask(root,1,n,w[t],w[y],1); ans=max(ans,mx-r1);ans=max(ans,r3);mx=max(mx,r2); ans=max(ans,mx-mn); printf("%d\n",ans); } void modify_tree(int x,int y,int z) { int f1=top[x],f2=top[y]; while (f1!=f2) { if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);} modify(root,1,n,w[f1],w[x],z); x=fath[f1];f1=top[x]; } if (dis[x]>dis[y]) swap(x,y); modify(root,1,n,w[x],w[y],z); } int main() { n=read(); for (int i=1;i<=n;i++) val[i]=read(); for (int i=1;i<=n-1;i++) { x=read();y=read(); addedge(x,y);addedge(y,x); } dfs1(1); dfs2(1,1); build(root,1,n); m=read(); for (int i=1;i<=m;i++) { x=read();y=read();z=read(); find_answer(x,y,z); modify_tree(x,y,z); } return 0; }