再见树剖,写代码四十分钟,debug一小时
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
typedef long long ll;
using namespace std;
#define rep(i,j,n) for(ll i=j;i<=n;i++)
#define per(i,j,n) for(ll i=j;i>=n;i--)
typedef unsigned long long ull;
typedef unsigned short us;
const ll INF= 1e17+7;
const ll maxx = 1e5+50;
const double eps=1e-8;
inline bool read(ll &num){char in;bool IsN=false;in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m;
ll head[maxx*2],cnt=0;
ll num=0;
ll top[maxx],son[maxx],size[maxx],id[maxx],fa[maxx];
ll a[maxx];
ll deep[maxx];
ll maxl[maxx*4],sum[maxx*4];
ll wt[maxx];
struct stu
{
ll to,next;
}A[maxx*2];
void add(ll u,ll v)
{
A[cnt].to=v;
A[cnt].next=head[u];
head[u]=cnt++;
}
void dfs1(ll now,ll f)
{
fa[now]=f;
size[now]=1;
deep[now]=deep[f]+1;
ll k=0;
for(ll i=head[now];~i;i=A[i].next)
{
ll p=A[i].to;
if(p!=f)
{
dfs1(p,now);
size[now]+=size[p];
if(size[p]>k)
{
k=size[p];
son[now]=p;
}
}
}
}
void dfs2(ll now,ll f)
{
top[now]=f;
id[now]=++num;
wt[num]=a[now];
if(son[now]==0) return ;
dfs2(son[now],f);
for(ll i=head[now];~i;i=A[i].next)
{
ll p=A[i].to;
if(p!=fa[now]&&p!=son[now])
{
dfs2(p,p);
}
}
}
void pushup(ll x)
{
maxl[x]=max(maxl[x<<1],maxl[x<<1|1]);
sum[x]=sum[x<<1]+sum[x<<1|1];
}
void build(ll x,ll l,ll r)
{
if(l==r)
{
maxl[x]=wt[l];
sum[x]=wt[l];
return ;
}
ll mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
void modify(ll x,ll l,ll r,ll k,ll val) // k=val
{
if(l==r)
{
sum[x]=val;
maxl[x]=val;
return ;
}
ll mid=(l+r)>>1;
if(k<=mid)
modify(x<<1,l,mid,k,val);
if(k>mid)
modify(x<<1|1,mid+1,r,k,val);
pushup(x);
}
ll query0(ll x,ll l,ll r,ll ql,ll qr) // zuidazhi
{
if(ql<=l&&qr>=r)
{
return maxl[x];
}
ll ans=-INF;
ll mid=(l+r)>>1;
if(ql<=mid) ans=max(ans,query0(x<<1,l,mid,ql,qr));
if(qr>mid) ans=max(ans,query0(x<<1|1,mid+1,r,ql,qr));
return ans;
}
ll query1(ll x,ll l,ll r,ll ql,ll qr)
{
if(ql<=l&&qr>=r)
{
return sum[x];
}
ll ans=0;
ll mid=(l+r)>>1;
if(ql<=mid) ans+=query1(x<<1,l,mid,ql,qr);
if(qr>mid) ans+=query1(x<<1|1,mid+1,r,ql,qr);
return ans;
}
ll ask0(ll x,ll y)
{
ll ans=-INF;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]] )
swap(x,y);
ans=max(ans,query0(1,1,n,id[top[x]],id[x] ));
x=fa[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
ans=max(ans, query0(1,1,n,id[x],id[y]) );
return ans;
}
ll ask1(ll x,ll y)
{
ll ans=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]] )
swap(x,y);
ans+=query1(1,1,n,id[top[x]],id[x] );
x=fa[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
ans+=query1(1,1,n,id[x],id[y]);
return ans;
}
int main()
{
ll t,s,q;
while(scanf("%lld%lld",&n,&q)!=EOF)
{
rep(i,1,n) scanf("%lld",&a[i]);
rep(i,1,n)
{
id[i]=0;
son[i]=0;
head[i]=-1;
size[i]=0;
top[i]=0;
deep[i]=0;
}
cnt=0;
num=0;
ll x,y;
rep(i,1,n-1)
{
scanf("%lld%lld",&x,&y);
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
ll f;
while(q--)
{
scanf("%lld%lld%lld",&f,&x,&y);
if(f==0)
{
printf("%lld\n",ask0(x,y));
}
if(f==1)
{
printf("%lld\n",ask1(x,y));
}
if(f==2)
{
modify(1,1,n,id[x],y);
}
}
}
return 0;
}
/*
*/