rt,调吐了,求助dalao,暂时没找到hack数据
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
char c; int x=0,f=1; c=getchar();
while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar(); }
while(c>='0'&&c<='9'){ x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
return x*f;
}
int dep[100001],top[100001],rnk[100001],fa[100001],dfn[100001],siz[100001];
int cnt,n,m,wson[100001],w[100001];
vector<int> edge[100001];
struct node{
int l,r,f,maxr,maxl,maxn,sum;
node() {sum=maxl=maxr=maxn=0;}
} tree[400001];
inline void dfs1(int u){
wson[u]=-1;
siz[u]=1;
for(register int i=0;i<edge[u].size();i++){
int v=edge[u][i];
if(!dep[v]){
dep[v]=dep[u]+1;
fa[v]=u;
dfs1(v);
siz[u]+=siz[u];
if(wson[u]==-1||siz[wson[u]]<siz[v]) wson[u]=v;
}
}
}
inline void dfs2(int u,int t){
top[u]=t;
dfn[u]=++cnt;
rnk[cnt]=u;
if(wson[u]==-1) return;
dfs2(wson[u],t);
for(register int i=0;i<edge[u].size();i++){
int v=edge[u][i];
if(v!=fa[u]&&v!=wson[u]) dfs2(v,v);
}
}
inline void push_up(int k){
tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
tree[k].maxr=max(tree[k<<1|1].maxr,tree[k<<1].maxr+tree[k<<1|1].sum);
tree[k].maxl=max(tree[k<<1].maxl,tree[k<<1|1].maxl+tree[k<<1].sum);
tree[k].maxn=max(tree[k<<1|1].maxl+tree[k<<1].maxr,max(tree[k<<1].maxn,tree[k<<1|1].maxn));
}
inline void push_down(int k){
tree[k<<1].sum=(tree[k<<1].r-tree[k<<1].l+1)*tree[k].f;
if(tree[k<<1].sum>0) tree[k<<1].maxn=tree[k<<1].maxr=tree[k<<1].maxl=tree[k<<1].sum;
else tree[k<<1].maxn=tree[k<<1].maxr=tree[k<<1].maxl=0;
tree[k<<1|1].sum=(tree[k<<1|1].r-tree[k<<1|1].l+1)*tree[k].f;
if(tree[k<<1|1].sum>0) tree[k<<1|1].maxn=tree[k<<1|1].maxr=tree[k<<1|1].maxl=tree[k<<1|1].sum;
else tree[k<<1|1].maxn=tree[k<<1|1].maxr=tree[k<<1|1].maxl=0;
tree[k].f=1e9;
}
inline void build(int l,int r,int k){
tree[k].l=l; tree[k].r=r; tree[k].f=1e9; tree[k].sum=0;
tree[k].maxr=tree[k].maxl=tree[k].maxn=-1e18;
if(l==r){
tree[k].maxr=tree[k].maxl=tree[k].maxn=tree[k].sum=w[rnk[l]];
return;
}
int mid=(l+r)>>1;
build(l,mid,k<<1); build(mid+1,r,k<<1|1);
push_up(k);
}
inline void change_interval(int k,int a,int b,int y){
if(tree[k].l>=a&&tree[k].r<=b){
tree[k].sum=(tree[k].r-tree[k].l+1)*y;
if(tree[k].sum>0) tree[k].maxn=tree[k].maxr=tree[k].maxl=tree[k].sum;
else tree[k].maxn=tree[k].maxr=tree[k].maxl=0;
tree[k].f=y;
return;
}
if(tree[k].f!=1e9) push_down(k);
int mid=(tree[k].l+tree[k].r)>>1;
if(a<=mid) change_interval(k<<1,a,b,y);
if(b>mid) change_interval(k<<1|1,a,b,y);
push_up(k);
}
inline node ask_interval(int k,int a,int b){
if(tree[k].l>=a&&tree[k].r<=b){
return tree[k];
}
if(tree[k].f!=1e9) push_down(k);
int mid=(tree[k].l+tree[k].r)>>1;
if(b<=mid) return ask_interval(k<<1,a,b);
else{
if(a>mid) return ask_interval(k<<1|1,a,b);
else{
node t,a1=ask_interval(k<<1,a,b),b1=ask_interval(k<<1|1,a,b);
t.sum=a1.sum+b1.sum;
t.maxr=max(b1.maxr,a1.maxr+b1.sum);
t.maxl=max(a1.maxl,b1.maxl+a1.sum);
t.maxn=max(a1.maxr+b1.maxl,max(a1.maxn,b1.maxn));
return t;
}
}
}
inline void change(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
change_interval(1,dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
change_interval(1,dfn[x],dfn[y],z);
}
inline node merge(node a,node b){
node t;
t.sum=a.sum+b.sum;
t.maxr=max(b.maxr,a.maxr+b.sum);
t.maxl=max(a.maxl,b.maxl+a.sum);
t.maxn=max(a.maxr+b.maxl,max(a.maxn,b.maxn));
t.f=1e9;
return t;
}
inline node ask(int x,int y){
node L,R;
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]){
L=merge(ask_interval(1,dfn[top[x]],dfn[x]),L);
x=fa[top[x]];
}
else {
R=merge(ask_interval(1,dfn[top[y]],dfn[y]),R);
y=fa[top[y]];
}
}
if(dep[x]>dep[y]){
L=merge(ask_interval(1,dfn[y],dfn[x]),L);
}
else R=merge(ask_interval(1,dfn[x],dfn[y]),R);
swap(L.maxl,L.maxr);
return merge(L,R);
}
signed main()
{
n=read();
for(register int i=1;i<=n;i++){
w[i]=read();
}
for(register int i=1;i<=n-1;i++){
int u=read(),v=read();
edge[u].push_back(v);
edge[v].push_back(u);
}
dep[1]=1; dfs1(1); dfs2(1,1); build(1,n,1);
m=read();
while(m--){
int opt=read(),x=read(),y=read();
if(opt==1){
printf("%lld\n",ask(x,y).maxn);
}
if(opt==2){
int c=read();
change(x,y,c);
}
}
return 0;
}