1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| #include<bits/stdc++.h> #define int long long #define ls o<<1 #define rs o<<1|1 using namespace std; const int N=2e5+5,inf=1e9; int n,m,a[N]; int sz[N],dep[N],wc[N],dfn[N],cnt,seq[N],top[N],fa[N]; vector<int> g[N]; void dfs1(int u,int from){ dep[u]=dep[from]+1,sz[u]=1,fa[u]=from; for(int v:g[u]){ if(v==from) continue; dfs1(v,u); sz[u]+=sz[v]; if(sz[v]>sz[wc[u]]) wc[u]=v; } } void dfs2(int u,int Top){ dfn[u]=++cnt,seq[cnt]=u; top[u]=Top; if(wc[u]!=0){ dfs2(wc[u],Top); for(int v:g[u]) if(v!=fa[u]&&v!=wc[u]) dfs2(v,v); } } struct node{ int qh,hq,mx,mn,add; node operator +(const node&w)const{ return {max({qh,w.qh,mx-w.mn}),max({hq,w.hq,w.mx-mn}),max(mx,w.mx),min(mn,w.mn),0}; } }tr[N<<2]; void pushup(int o){ tr[o]=tr[ls]+tr[rs]; } void tag(int o,int l,int r,int add){ tr[o].add+=add,tr[o].mx+=add,tr[o].mn+=add; } void pushdown(int o,int l,int r){ int mid=l+r>>1; tag(ls,l,mid,tr[o].add); tag(rs,mid+1,r,tr[o].add); tr[o].add=0; } void build(int o,int l,int r){ if(l==r){ tr[o]={0,0,a[seq[l]],a[seq[l]],0}; return; } int mid=l+r>>1; build(ls,l,mid); build(rs,mid+1,r); pushup(o); } void update(int o,int l,int r,int L,int R,int x){ if(l>=L&&r<=R){ tag(o,l,r,x); return; } pushdown(o,l,r); int mid=l+r>>1; if(L<=mid) update(ls,l,mid,L,R,x); if(R>mid) update(rs,mid+1,r,L,R,x); pushup(o); } node query(int o,int l,int r,int L,int R){ if(l>=L&&r<=R) return tr[o]; pushdown(o,l,r); int mid=l+r>>1; node res={0,0,0,inf,0}; if(L<=mid) res=res+query(ls,l,mid,L,R); if(R>mid) res=res+query(rs,mid+1,r,L,R); return res; } void upd(int x,int y,int z){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); update(1,1,n,dfn[top[x]],dfn[x],z); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); update(1,1,n,dfn[x],dfn[y],z); } int qry(int x,int y){ node l,r; l=r={0,0,0,inf,0}; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]){ r=query(1,1,n,dfn[top[y]],dfn[y])+r; y=fa[top[y]]; } else{ l=query(1,1,n,dfn[top[x]],dfn[x])+l; x=fa[top[x]]; } } if(dep[x]>dep[y]) l=query(1,1,n,dfn[y],dfn[x])+l; else r=query(1,1,n,dfn[x],dfn[y])+r; swap(l.qh,l.hq); return (l+r).hq; } signed main(){ ios::sync_with_stdio(0);cin.tie(0); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<n;i++){ int u,v; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } dfs1(1,0); dfs2(1,0); build(1,1,n); cin>>m; while(m--){ int x,y,z; cin>>x>>y>>z; cout<<qry(x,y)<<'\n'; upd(x,y,z); } return 0; }
|