题解:
一道模板题。
树链剖分+线段树。
码农题。
写得心态爆炸。
纪念一下。
C
o
d
e
:
Code:
Code:
#include<bits/stdc++.h>
#define ll long long
const int N=1e5+5;
using namespace std;
int n,m,head[N*2],a[N],size[N],son[N],tot,fi[N],en[N];
int belong[N],cnt,fa[N],b[N];
long long tree[N*4],add[N*4];
inline int read()
{
int x=0,f=1;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
return x*f;
}
struct node
{
int vet,next;
}edge[N*2];
void Add(int u,int v)
{
edge[++tot].vet=v;
edge[tot].next=head[u];
head[u]=tot;
}
void pushdown(int o,int l,int r)
{
int mid=(l+r)>>1;
if(add[o])
{
add[o<<1]+=add[o];
add[o<<1|1]+=add[o];
tree[o<<1]+=(long long)(mid-l+1)*add[o];
tree[o<<1|1]+=(long long)(r-mid)*add[o];
add[o]=0;
}
}
void dfs1(int u,int father)
{
size[u]=1;
int mx=0;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].vet;
if(v!=father)
{
fa[v]=u;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>mx)
{
mx=size[v];
son[u]=v;
}
}
}
}
void dfs2(int u,int top)
{
belong[u]=top;
fi[u]=++cnt;b[cnt]=u;
if(son[u])dfs2(son[u],top);
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].vet;
if(v!=fa[u]&&v!=son[u])dfs2(v,v);
}
en[u]=cnt;
}
void build(int o,int l,int r)
{
if(l==r)
{
tree[o]=a[b[l]];
return;
}
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
tree[o]=tree[o<<1]+tree[o<<1|1];
}
void update(int o,int l,int r,int x,int y,int t)
{
if(l>y||r<x)return;
if(l>=x&&r<=y)
{
add[o]+=t;
tree[o]+=(long long)(r-l+1)*t;
return;
}
pushdown(o,l,r);
int mid=(l+r)>>1;
update(o<<1,l,mid,x,y,t);
update(o<<1|1,mid+1,r,x,y,t);
tree[o]=tree[o<<1]+tree[o<<1|1];
}
long long query(int o,int l,int r,int x,int y)
{
if(l>y||r<x)return 0;
if(l>=x&&r<=y)return tree[o];
pushdown(o,l,r);
int mid=(l+r)>>1;
return query(o<<1,l,mid,x,y)+query(o<<1|1,mid+1,r,x,y);
}
long long queryans(int x)
{
long long ans=0;
while(belong[x]!=1)
{
ans+=query(1,1,n,fi[belong[x]],fi[x]);
x=fa[belong[x]];
}
ans+=query(1,1,n,1,fi[x]);
return ans;
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
while(m--)
{
int id=read();
if(id==1)
{
int x=read(),y=read();
update(1,1,n,fi[x],fi[x],y);
}else
if(id==2)
{
int x=read(),y=read();
update(1,1,n,fi[x],en[x],y);
}else
{
int x=read();
printf("%lld\n",queryans(x));
}
}
return 0;
}