#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll ;
struct my{
ll next;
ll v;
};
const int maxn=500000+20;
my tu[maxn];
ll d[maxn],size[maxn],fa[maxn],myson[maxn];
ll sum[maxn*8],lazy[maxn*8];
ll dfsn[maxn],last[maxn],top[maxn],pre[maxn];
ll dfn;
ll n,m;
ll adj[maxn];
ll w[maxn];
ll tot;
void myinsert(ll u,ll v){
tu[++tot].v=v;
tu[tot].next=adj[u];
adj[u]=tot;
}
void dfs1(int u,int f){
size[u]=1;
for (int i=adj[u];i;i=tu[i].next){
int v=tu[i].v;
if(v==f) continue;
d[v]=d[u]+1;fa[v]=u;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[myson[u]]) myson[u]=v;
}
}
void dfs2(int u,int frist){
dfsn[u]=++dfn;
pre[dfn]=u;
top[u]=frist;
if(myson[u]) dfs2(myson[u],frist);
for (int i=adj[u];i;i=tu[i].next){
int v=tu[i].v;
if(v==fa[u]||v==myson[u]) continue;
dfs2(v,v);
}
last[u]=dfn;
}
void pushup(ll x){
sum[x]=sum[x<<1]+sum[x<<1|1];
}
void build(ll l,ll r,ll rt){
if(l==r){
sum[rt]=w[pre[l]];
return ;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
pushup(rt);
}
void pushdown(ll x,ll ln,ll rn){
if(lazy[x]){
sum[x<<1]+=lazy[x]*ln;
sum[x<<1|1]+=lazy[x]*rn;
lazy[x<<1]+=lazy[x];
lazy[x<<1|1]+=lazy[x];
lazy[x]=0;
}
}
void change(ll l,ll r,ll rt,ll L,ll R,ll c){
if(L<=l&&r<=R){
sum[rt]+=c*(r-l+1);
lazy[rt]+=c;
return ;
}
ll mid=(l+r)>>1;
pushdown(rt,mid-l+1,r-mid);
if(L<=mid) change(l,mid,rt<<1,L,R,c);
if(R>mid) change(mid+1,r,rt<<1|1,L,R,c);
pushup(rt);
}
ll query(ll l,ll r,ll rt,ll L,ll R){
if(L<=l&&r<=R){
return sum[rt];
}
ll mid=(l+r)>>1;
ll ans=0;
pushdown(rt,mid-l+1,r-mid);
if(L<=mid) ans+=query(l,mid,rt<<1,L,R);
if(R>mid) ans+=query(mid+1,r,rt<<1|1,L,R);
return ans;
}
ll getans(ll u){
long long tu=top[u],ans=0;
while (tu!=1){
ans+=query(1,n,1,dfsn[tu],dfsn[u]);
u=fa[tu];
tu=top[u];
}
ans+=query(1,n,1,dfsn[1],dfsn[u]);
return ans;
}
int main(){
scanf("%lld%lld",&n,&m);
for (ll i=1;i<=n;i++){
scanf("%lld",&w[i]);
}
ll u,v;
for (ll i=1;i<n;i++){
scanf("%lld%lld",&u,&v);
myinsert(u,v);
myinsert(v,u);
}
d[1]=1;
fa[1]=-1;
dfs1(1,-1);
dfs2(1,1);
n;
build(1,n,1);
ll biao;
ll x;
ll a;
while(m--){
scanf("%lld",&biao);
if(biao==1) {
scanf("%lld%lld",&x,&a);
change(1,n,1,dfsn[x],dfsn[x],a);
}
if(biao==2){
scanf("%lld%lld",&x,&a);
change(1,n,1,dfsn[x],last[x],a);
}
if(biao==3) {
scanf("%lld",&x);
printf("%lld\n",getans(x));
}
}
return 0;
}
haoi2015 树上操作
Posted lmjer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了haoi2015 树上操作相关的知识,希望对你有一定的参考价值。
以上是关于haoi2015 树上操作的主要内容,如果未能解决你的问题,请参考以下文章