记录编号 413535 评测结果 AAAAAAAAAA
题目名称 [HAOI 2015]树上操作 最终得分 100
用户昵称 GravatarHzoi_Maple 是否通过 通过
代码语言 C++ 运行时间 0.862 s
提交时间 2017-06-11 18:28:08 内存使用 13.67 MiB
显示代码纯文本
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ll long long
int n,m,x,y,z,w[200001];
int adj[200001],num;
ll add[400001],zh[400001];
struct kk
{
	int s,t,next;
}k[200001];
void swap(ll &a,ll &b){
	ll c=a;
	a=b;
	b=c;
}
inline int read(){
	int zh=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		zh=zh*10+ch-'0';
		ch=getchar();
	}
	return zh*f;
}
inline void pushup(int i)
{
    zh[i]=zh[i<<1]+zh[i<<1|1];
}
void init(int x,int y){
	k[num].s=x;
	k[num].t=y;
	k[num].next=adj[x];
	adj[x]=num++;
}
int fa[100001],dp[100001],son[100001],size[100001];
void Dfs1(int x,int father,int dep){
	fa[x]=father;dp[x]=dep;
	size[x]=1;son[x]=0;
	for(int i=adj[x];i!=-1;i=k[i].next){
		int o=k[i].t;
		if(o!=father){
			Dfs1(o,x,dep+1);
			size[x]+=size[o];
			if(size[son[x]]<size[o])
				son[x]=o;
		}
	}
}
int top[100001],id[100001],cnt,pos[100001];
int wcx[100001],yl[100001];//记得某皮说过:只可意会不可言传~ 
void Dfs2(int u,int tp){
	top[u]=tp;id[u]=++cnt;
	pos[cnt]=u;wcx[u]=cnt;
	if(son[u])
		Dfs2(son[u],tp);
	for(int i=adj[u];i!=-1;i=k[i].next){
		int o=k[i].t;
		if(o!=fa[u]&&o!=son[u]){
			Dfs2(o,o);
		}
	}	
	yl[u]=cnt;
}
void build(int l,int r,int x){
	add[x]=0;
	if(l==r){
		zh[x]=w[pos[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,x<<1);
	build(mid+1,r,x<<1|1);
	zh[x]=zh[x<<1]+zh[x<<1|1];
}
void pushd(int x,int len){
	if(add[x]){
		add[x<<1]+=add[x];
		add[x<<1|1]+=add[x];
		zh[x<<1]+=add[x]*(len-(len>>1));
		zh[x<<1|1]+=add[x]*(len>>1);
		add[x]=0;
	}
}
void update(int L,int R,ll c,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
      add[rt]+=c;
      zh[rt]+=(ll)c*(r-l+1);
      return;
    }
    pushd(rt,r-l+1);
    int mid=(l+r)>>1;
    if(L<=mid)
      update(L,R,c,l,mid,2*rt);
    if(mid<R)
      update(L,R,c,mid+1,r,2*rt+1);
    pushup(rt);
}
ll ask(int s,int t,int l,int r,int x){
    if(s<=l&&t>=r) return zh[x];
    pushd(x,r-l+1);
    int mid=(l+r)>>1;ll ans=0;
    if(s<=mid) ans+=ask(s,t,l,mid,2*x);
    if(t>mid) ans+=ask(s,t,mid+1,r,2*x+1);
    return ans;
}
ll query(int x,int y){
    int fx=top[x],fy=top[y];
    ll res=0;
    while(fx^fy){
        if(dp[fx]<dp[fy]){
            swap(x,y);
            swap(fx,fy);
        }
        res+=ask(id[fx],id[x],1,n,1);
        x=fa[fx];fx=top[x];
    }
    if(dp[x]>dp[y]) swap(x,y);
    res+=ask(id[x],id[y],1,n,1);
    return res;
}
int main()
{
	freopen("haoi2015_t2.in","r",stdin);
	freopen("haoi2015_t2.out","w",stdout);
	memset(adj,-1,sizeof(adj));
	n=read();m=read();
	for(int i=1;i<=n;++i)
		w[i]=read();
	for(int i=1;i<n;++i){
		x=read();y=read();
		init(x,y);
		init(y,x);
	}
	Dfs1(1,0,0);
	Dfs2(1,1);
	build(1,n,1);
	for(int i=1;i<=m;++i){
		x=read();
		if(x==1){
			y=read();z=read();
			update(wcx[y],wcx[y],z,1,n,1);
		}
		if(x==2){
			y=read();z=read();
			update(wcx[y],yl[y],z,1,n,1);
		}
		if(x==3){
			y=read();
			printf("%lld\n",query(1,y));
		}
	}
	// while(1);
	return 0;
}