记录编号 161266 评测结果 AAAAAAAAAA
题目名称 [HAOI 2015]树上操作 最终得分 100
用户昵称 Gravatardydxh 是否通过 通过
代码语言 C++ 运行时间 0.863 s
提交时间 2015-05-03 12:48:15 内存使用 17.10 MiB
显示代码纯文本
/*
Problem:HAOI2015_T2;
Language:c++;
by dydxh;
2015.5.1;
*/
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ctime>
#include<queue>
#include<set>
#include<map>
#include<cstdio>
using namespace std;
const int maxn=100005;
const int oo=2000000000;
int n,m,cnt=0,len=0,yy,x;
int linkk[maxn],dep[maxn],l[maxn],r[maxn];
long long v[maxn],up_k,up_b;
struct seg
{
	long long k,b,delta_b,delta_k;
}tree[maxn<<2];
struct edge
{
	int y,next;
}e[maxn<<1];
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
void insert(int a,int b)
{
	e[++len].next=linkk[a];
	linkk[a]=len;
	e[len].y=b;
	e[++len].next=linkk[b];
	linkk[b]=len;
	e[len].y=a;
}
int id[maxn],stack[maxn],top=0;
void dfs()
{
	/*l[now]=++cnt,dep[now]=dep[father]+1,v[now]=v[father]+v[now];
	for(int i=linkk[now];i;i=e[i].next)
	{
		int tn=e[i].y;
		if(tn==father)
			continue;
		dfs(tn,now);
	}
	r[now]=cnt;*/
	memset(id,0,sizeof(id));
	memset(l,0,sizeof(l));
	memset(r,0,sizeof(r));
	for(int i=1;i<=n;i++)
		id[i]=linkk[i];
	stack[++top]=1,stack[0]=0;
	while(top)
	{
		int now=stack[top];
		if(!l[now])
			l[now]=++cnt,dep[now]=dep[stack[top-1]]+1,v[now]=v[stack[top-1]]+v[now];
		if(id[now])
		{
			int edgee=id[now];
			id[now]=e[edgee].next;
			if(e[edgee].y==stack[top-1])
				continue;
			stack[++top]=e[edgee].y;
		}
		else
			r[stack[top--]]=cnt;
	}
}
void up_data(int leftt,int rightt,int root)
{
	if(leftt>r[yy] || rightt<l[yy])
		return ;
	if(l[yy]<=leftt && rightt<=r[yy])
	{
		tree[root].delta_b+=up_b,tree[root].b+=up_b;
		tree[root].delta_k+=up_k,tree[root].k+=up_k;
		return ;
	}
	int mid=(leftt+rightt)>>1;
	up_data(leftt,mid,root<<1);
	up_data(mid+1,rightt,root<<1|1);
}
long long ask(int leftt,int rightt,int root)
{
	if(leftt>l[yy] || rightt<l[yy])
		return 0;
	if(l[yy]==leftt && rightt==l[yy])
		return 1LL*tree[root].k*dep[yy]+tree[root].b;
	if(tree[root].delta_b!=0)
	{
		tree[root<<1].delta_b+=tree[root].delta_b;
		tree[root<<1].b+=tree[root].delta_b;
		tree[root<<1|1].delta_b+=tree[root].delta_b;
		tree[root<<1|1].b+=tree[root].delta_b;
		tree[root].delta_b=0;
	}
	if(tree[root].delta_k!=0)
	{
		tree[root<<1].delta_k+=tree[root].delta_k;
		tree[root<<1].k+=tree[root].delta_k;
		tree[root<<1|1].delta_k+=tree[root].delta_k;
		tree[root<<1|1].k+=tree[root].delta_k;
		tree[root].delta_k=0;
	}
	int mid=(leftt+rightt)>>1;
	long long ll=ask(leftt,mid,root<<1);
	long long rr=ask(mid+1,rightt,root<<1|1);
	return rr+ll;
}
void dydxh()
{
	while(m--)
	{
		int opt=read();
		if(opt==1)
		{
			yy=read(),x=read();
			up_b=x,up_k=0;
			up_data(1,n,1);
		}
		else if(opt==2)
		{
			yy=read(),x=read();
			up_b=1LL*x*(1-dep[yy]),up_k=x;
			up_data(1,n,1);
		}
		else
		{
			yy=read();
			long long ans=ask(1,n,1)+v[yy];
			printf("%lld\n",ans);
		}
	}
}
int main()
{
	freopen("haoi2015_t2.in","r",stdin);
	freopen("haoi2015_t2.out","w",stdout);
	memset(tree,0,sizeof(tree));
	n=read(),m=read();
	for(int i=1;i<=n;i++)
		v[i]=read();
	int a,b;
	for(int i=1;i<n;i++)
	{
		a=read(),b=read();
		insert(a,b);
	}
	dep[0]=-1,v[0]=0;
	dfs();
	dydxh();
	//cout<<"Time has passed:"<<1.0*clock()/1000<<"s!"<<endl;
	return 0;
}