P3178 [HAOI2015]树上操作 的dfs序题解
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。
//点修改+树修改,(点->根)链查询
#include<bits/stdc++.h>
#define ll long long
#define rint register int
using namespace std;
const int N=1e6+5;
int n,m,root,cnt,tim;
int h[N],be[N],en[N],dep[N];
ll d[N],s1[N],s2[N],size[N],s[N];
struct edge
{
int v,nxt;
} e[N<<1];
inline ll read()
{
ll x=0;
bool flag=false;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') flag=true;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return flag?~x+1:x;
}
void add_edge(int u,int v)
{
e[++cnt].v=v;
e[cnt].nxt=h[u];
h[u]=cnt;
}
void dfs(int u,int fat)
{
dep[u]=dep[fat]+1;
be[u]=++tim;
size[u]+=d[u];//记录到根节点的距离
for(rint i=h[u];i;i=e[i].nxt)
{
int v=e[i].v;
if(v!=fat)
{
size[v]+=size[u];
dfs(v,u);
}
}
en[u]=tim;
}
void add(int x,ll c)
{
if (x==0) return ;
for (rint i=x;i<=n;i+=(i&(-i)))
{
s[i]+=c;
}
}
void add1(int x,ll c)//处理s1 记录v的变化
{
if(x==0) return;
for(rint i=x;i<=n;i+=(i&(-i)))
s1[i]+=c;
}
void add2(int x,ll c)//处理s2 记录dep的乘积
{
if(x==0) return;
for(rint i=x;i<=n;i+=(i&(-i)))
s2[i]+=c;
}
ll sum(int x)
{
ll ans=0;
for(rint i=x;i;i-=(i&(-i)))
{
ans+=s[i];
}
return ans;
}
ll sum1(int x)//求v的和
{
ll ans=0;
for(rint i=x;i;i-=(i&(-i)))
ans+=s1[i];
return ans;
}
ll sum2(int x)//求乘积的和
{
ll ans=0;
for(rint i=x;i;i-=(i&(-i)))
ans+=s2[i];
return ans;
}
int main()
{
n=read(),m=read(),root=1;
for(rint i=1;i<=n;++i)
d[i]=read();
for(rint i=1;i<n;++i)
{
int x=read(),y=read();
add_edge(x,y);
add_edge(y,x);
}
dfs(root,0);
for(rint i=1;i<=m;++i)
{
int op=read();//(deep[y]-deep[x]+1)*v=v*(deep[y]+1)-v*deep[x]
if(op==1)
{
int x=read();ll w=read();
add(be[x],w);add(en[x]+1,-w);//差分记录v
}
if(op==2)
{
int x=read();ll w=read();
add1(be[x],w);add1(en[x]+1,-w);//差分记录v
add2(be[x],dep[x]*w);add2(en[x]+1,-dep[x]*w);//差分记录dep*v
}
if(op==3)
{
int a=read();
ll ans=size[a];//先加上原数据
ans+=((dep[a]+1)*sum1(be[a])-sum2(be[a]));//子树修改求和
ans+=sum(be[a]);//点修改求和
printf("%lld\n",ans);
}
}
}
/*
in
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
out
6
9
13
*/
浙公网安备 33010602011771号