RT,不知哪里出了nt错误,求dalao看看
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=112345;
const int maxm=212345;
int tot,cnt;
int lin[maxn],to[maxn],ne[maxn],in[maxn];
long long m,n,a[maxn],va[maxn];//
int dfn[maxn],top[maxn];
int siz[maxn],fa[maxn];
int dep[maxn],son[maxn];
struct node{
int l,r;
long long s,f;
#define l(x) c[x].l
#define r(x) c[x].r
#define s(x) c[x].s
#define f(x) c[x].f
}c[maxn<<2];
void add(int u,int v)//链式前向星
{
to[++tot]=v;
ne[tot]=lin[u];
lin[u]=tot;
}
---------树剖两个dfs------------
void dfs1(int s,int ff)
{
siz[s]=1;
int mm=-1;
for(int i=lin[s];i;i=ne[i])
{
int t=to[i];
if(t==ff)
continue;
dep[t]=dep[s]+1;
fa[t]=s;
dfs1(t,s);
siz[s]+=siz[t];
if(siz[t]>mm)
{
mm=siz[t];
son[s]=t;
}
}
}
void dfs2(int s,int ff)
{
cnt++;
dfn[s]=cnt;
va[cnt]=a[s];
top[s]=ff;
if(!son[s])
return ;
dfs2(son[s],ff);
for(int i=lin[s];i;i=ne[i])
{
int t=to[i];
if(t==fa[s]||t==son[s])
continue;
dfs2(t,t);
}
}
---------------树剖两个dfs结束---------
------------------线段树开始-------------
void updat(int w)//更新(因为懒,所以只有一行也要写个函数)
{
s(w)=s(w<<1)+s(w<<1|1);
return ;
}
void spread(int w)//下放标记
{
if(f(w))
{
f(w<<1)+=f(w);
f(w<<1|1)+=f(w);
s(w<<1)+=(f(w)*1ll*(r(w<<1)-l(w<<1)+1));
s(w<<1|1)+=(f(w)*1ll*(r(w<<1|1)-l(w<<1|1)+1));
f(w)=0;
}
}
void build(int l,int r,int w)//建树
{
l(w)=l,r(w)=r;
if(l==r)
{
s(w)=va[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,w<<1);
build(mid+1,r,w<<1|1);
updat(w);
return ;
}
void change(int l,int r,int k,int w)//修改
{
if(l(w)>=l&&r(w)<=r)
{
s(w)+=1ll*k*(r(w)-l(w)+1);
f(w)+=k*1ll;
return ;
}
spread(w);
int mid=(l(w)+r(w))>>1;
if(l<=mid)
change(l,r,k,w<<1);
if(r>mid)
change(l,r,k,w<<1|1);
updat(w);
return ;
}
long long ask(int l,int r,int w)//询问
{
if(l(w)>=l&&r(w)<=r)
{
return s(w);
}
spread(w);
int mid=(l(w)+r(w))>>1;
long long ans=0;
if(l<=mid)
ans+=ask(l,r,w<<1);
if(r>mid)
ans+=ask(l,r,w<<1|1);
return ans;
}
----------------线段树结束---------------
int main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for(int i=1;i<n;i++)
{
int u,b;
scanf("%d%d",&u,&b);
add(u,b);
in[b]++;
}
int root=0;
for(int i=1;i<=n;i++)//找根
if(in[i]==0)
{
root=i;
break;
}
dep[root]=1;
dfs1(root,0);
dfs2(root,root);
build(1,n,1);
for(int i=1;i<=m;i++)
{
int op,p,x;
scanf("%d%d",&op,&x);
if(op==1)
{
scanf("%d",&p);
change(dfn[x],dfn[x],p,1);
}
if(op==2)
{
scanf("%d",&p);
change(dfn[x],dfn[x]+siz[x]-1,p,1);
}
if(op==3)
{
long long ans=0;
int y=root;
while(top[y]!=top[x])
{
if(dep[top[y]]>dep[top[x]])
swap(x,y);
ans+=ask(dfn[top[x]],dfn[x],1);
x=fa[top[x]];
}
if(dep[x]>dep[y])
swap(x,y);
ans+=ask(dfn[x],dfn[y],1);
printf("%lld\n",ans);
}
}
return 0;
}