#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=200000+500,M=4*N;
struct node
{
int sum,lmax,rmax,ans;
int lazy;
}tree[4*N];
int fx,fy,fz;
int head[M],nex[M],to[M],son[M],siz[N],bz[N];
int dfn[N],tot,cnt,deep[N],fa[N];
int n,m;
int a[N],top[N];
void add(int x,int y)
{
tot++;
nex[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs1(int x,int dep)
{
bz[x]=1;
deep[x]=dep;
for(int i=head[x];i;i=nex[i])
{
int y=to[i];
if(bz[y]==0)
{
fa[y]=x;
dfs1(y,dep+1);
siz[x]+=siz[y];
if(siz[son[x]]<siz[y])son[x]=y;
}
}
siz[x]++;
}
void dfs2(int x,int topp)
{
bz[x]=1;
cnt++;
dfn[x]=cnt;
top[x]=topp;
if(!son[x])return ;
dfs2(son[x],topp);
for(int i=head[x];i;i=nex[i])
{
int y=to[i];
if(bz[y]==0&&y!=son[x])dfs2(y,y);
}
}
void change(int x)
{
tree[x].sum=tree[x+x].sum+tree[x+x+1].sum;
tree[x].ans=max(tree[x+x].ans,max(tree[x+x+1].ans,tree[x+x].rmax+tree[x+x+1].lmax));
tree[x].lmax=max(tree[x+x].lmax,tree[x+x].sum+tree[x+x+1].lmax);
tree[x].rmax=max(tree[x+x+1].rmax,tree[x+x+1].sum+tree[x+x].rmax);
}
void change1(int x,int l,int r,int z)
{
tree[x].lazy=z;
tree[x].sum=(r-l+1)*z;
tree[x].lmax=tree[x].rmax=tree[x].ans=max(0,tree[x].sum);
}
void down(int x,int l,int r)
{
int mid=(l+r)>>1;
if(tree[x].lazy)
{
change1(x+x,l,mid,tree[x].lazy);
change1(x+x+1,mid+1,r,tree[x].lazy);
}
tree[x].lazy=0;
}
void ch(int i,int l,int r)
{
if(fx>r||l>fy)return ;
if(fx<=l&&r<=fy)
{
change1(i,l,r,fz);
return ;
}
int mid=(l+r)>>1;
down(i,l,r);
ch(i+i,l,mid);
ch(i+i+1,mid+1,r);
change(i);
}
node q(int i,int l,int r)
{
if(fx>r||l>fy)return {0,0,0,0,0};
if(fx<=l&&r<=fy)return tree[i];
int mid=(l+r)>>1;down(i,l,r);
node ans1=q(i+i,l,mid);
node ans2=q(i+i+1,mid+1,r);
node noww={0,0,0,0,0};
noww.sum=ans1.sum+ans2.sum;
noww.lmax=max(ans1.lmax,ans1.sum+ans2.lmax);
noww.rmax=max(ans2.rmax,ans1.rmax+ans2.sum);
noww.ans=max(ans1.ans,max(ans2.ans,ans1.rmax+ans2.lmax));
change(i);
return noww;
}
void changed(int x,int y)
{
if(deep[x]<deep[y])swap(x,y);
while(deep[top[x]]>=deep[y])
{
fx=dfn[top[x]],fy=dfn[x];
ch(1,1,n);
x=fa[top[x]];
}
if(deep[x]>=deep[y])
{
fx=dfn[y],fy=dfn[x];
ch(1,1,n);
}
}
node got(int x,int y)
{
node ans={0,0,0,0,0};
if(deep[x]<deep[y])swap(x,y);
while(deep[top[x]]>=deep[y])
{
fx=dfn[top[x]],fy=dfn[x];
node now1=q(1,1,n);
ans.sum+=now1.sum;
ans.ans=max(ans.ans,max(now1.ans,now1.rmax+ans.lmax));
ans.rmax=max(ans.rmax,ans.sum+now1.rmax);
ans.lmax=max(ans.lmax+now1.sum,now1.lmax);
x=fa[top[x]];
}
if(deep[x]>=deep[y])
{
fx=dfn[y],fy=dfn[x];
node now1=q(1,1,n);
ans.sum+=now1.sum;
ans.ans=max(ans.ans,max(now1.ans,now1.rmax+ans.lmax));
ans.rmax=max(ans.rmax,ans.sum+now1.rmax);
ans.lmax=max(ans.lmax+now1.sum,now1.lmax);
}
return ans;
}
int LCA(int u,int v)
{
while(top[u]!=top[v])
{
if(deep[top[u]]>deep[top[v]])u=fa[top[u]];
else v=fa[top[v]];
}
if(deep[u]>deep[v])return v;
else return u;
}
void getans(int x,int y)
{
int lca=LCA(x,y),lca1,xx=x,yy=y;
if(lca==x||lca==y)printf("%d\n",got(x,y).ans);
else
{
while(deep[x]>deep[lca]+1)
{
if(deep[top[x]]>deep[lca])x=top[x];
if(deep[fa[x]]>deep[lca])x=fa[x];
}
lca1=x;
node ans1=got(lca,yy),ans2=got(xx,lca1);
ans2.ans=max(ans2.ans,max(ans1.ans,ans2.lmax+ans1.lmax));
printf("%d\n",ans2.ans);
}
}
void changeans(int x,int y)
{
int lca=LCA(x,y),lca1,xx=x,yy=y;
if(lca==x||lca==y)changed(x,y);
else
{
while(deep[x]>deep[lca]+1)
{
if(deep[top[x]]>deep[lca])x=top[x];
if(deep[fa[x]]>deep[lca])x=fa[x];
}
lca1=x;
changed(lca,yy),changed(xx,lca1);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs1(1,1);
memset(bz,0,sizeof(bz));
dfs2(1,1);
for(int i=1;i<=n;i++)
{
fx=fy=dfn[i];
fz=a[i];
ch(1,1,n);
}
scanf("%d",&m);
while(m--)
{
int opt;
int x,y,z;
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d",&x,&y);
getans(x,y);
}
else
{
scanf("%d%d%d",&x,&y,&z);
fz=z;
changeans(x,y);
}
}
}
我的方法有点不一样,把x->y拆成x->lca,lca->y,再分别搞。