TLE on 2,7,8,9,10
#include<bits/stdc++.h>
#define int long long
using namespace std;
long long n,m,root,siz[400100]={0},a[400100]={0},heavy[400100]={0},dy[400100]={0};
long long q,w,waycount=0,fa[400100]={0},dep[400100]={0},x,y,z,qq,ww;
long long head[400100]={0},num=1,dfn[400100]={0},ding[400100]={0};
struct fff
{
long long l,r,tag,num;
}tree[400100];
struct ff
{
long long to,next;
}way[400100];
long long push_down(long long idx)
{
tree[idx<<1].num+=tree[idx].tag*(tree[idx<<1].r-tree[idx<<1].l+1);
tree[idx<<1|1].num+=tree[idx].tag*(tree[idx<<1|1].r-tree[idx<<1|1].l+1);
tree[idx<<1].tag+=tree[idx].tag;
tree[idx<<1|1].tag+=tree[idx].tag;
tree[idx].tag=0;
return 0;
}
long long dfs1(long long idx,long long dad)
{
fa[idx]=dad;
dep[idx]=dep[dad]+1;
long long maxx=0;
for(long long i=head[idx];i!=-1;i=way[i].next)
{
long long vv=way[i].to;
if(vv!=dad)
{
dfs1(vv,idx);
siz[idx]+=siz[vv];
if(siz[vv]>maxx)
maxx=siz[vv],heavy[idx]=vv;
}
}
return 0;
}
long long dfs2(long long idx,long long top)
{
dfn[idx]=num;
dy[num]=idx;
num++;
ding[idx]=top;
if(siz[idx]==1)
return 0;
dfs2(heavy[idx],top);
for(long long i=head[idx];i!=-1;i=way[i].next)
{
long long vv=way[i].to;
if(vv==heavy[idx] || vv==fa[idx])
continue;
dfs2(vv,vv);
}
return 0;
}
long long add(long long u,long long v)
{
way[waycount].to=v;
way[waycount].next=head[u];
head[u]=waycount;
waycount++;
return 0;
}
long long update(long long idx)
{
if(tree[idx].l>ww || tree[idx].r<qq)
return 0;
if(tree[idx].l>=qq && tree[idx].r<=ww)
{
tree[idx].tag+=z;
tree[idx].num+=z*(tree[idx].r-tree[idx].l+1);
return 0;
}
push_down(idx);
update(idx<<1);
update(idx<<1|1);
tree[idx].num=tree[idx<<1].num+tree[idx<<1|1].num;
return 0;
}
long long build(long long l,long long r,long long idx)
{
tree[idx].l=l;
tree[idx].r=r;
if(l==r)
{
tree[idx].num=a[dy[l]];
return 0;
}
long long mid=(l+r)>>1;
build(l,mid,idx<<1);
build(mid+1,r,idx<<1|1);
tree[idx].num+=tree[idx<<1].num+tree[idx<<1|1].num;
return 0;
}
long long query(long long idx)
{
if(tree[idx].l>ww || tree[idx].r<qq)
return 0;
if(tree[idx].l>=qq && tree[idx].r<=ww)
return tree[idx].num;
push_down(idx);
long long s=0;
s+=query(idx<<1);
s+=query(idx<<1|1);
return s;
}
long long way_query(long long x,long long y)
{
long long s=0;
while(ding[x]!=ding[y])
{
if(dep[ding[x]]<dep[ding[y]])
swap(x,y);
qq=dfn[ding[x]],ww=dfn[x];
s+=query(1);
x=fa[ding[x]];
}
if(dep[x]>dep[y])
swap(x,y);
qq=dfn[x];ww=dfn[y];
s+=query(1);
return s;
}
long long way_add(long long x,long long y,long long z)
{
while(ding[x]!=ding[y])
{
if(dep[ding[x]]<dep[ding[y]])
swap(x,y);
qq=dfn[ding[x]],ww=dfn[x];
update(1);
x=fa[ding[x]];
}
if(dep[x]>dep[y])
swap(x,y);
qq=dfn[x];ww=dfn[y];
update(1);
return 0;
}
signed main()
{
memset(head,-1,sizeof(head));
root=1;
cin>>n>>m;
for(long long i=1;i<=n;i++)
cin>>a[i],siz[i]=1;
for(long long i=1;i<n;i++)
cin>>q>>w,add(q,w),add(w,q);
dfs1(root,root);
dfs2(root,root);
build(1,n,1);
for(long long i=0;i<m;i++)
{
cin>>q;
if(q==3)
{
cin>>x;y=1;
cout<<way_query(x,y)<<endl;
}
if(q==2)
{
cin>>x>>z;
qq=dfn[x],ww=dfn[x]+siz[x]-1;
update(1);
}
if(q==1)
{
cin>>x>>z;
qq=dfn[x],ww=dfn[x]+siz[x]-1;
update(1);
z=-1*z;
for(long long i=head[x];i!=-1;i=way[i].next)
{
long long vv=way[i].to;
if(fa[x]==vv)
continue;
qq=dfn[vv],ww=dfn[vv]+siz[vv]-1;
update(1);
}
}
}
return 0;
}