记录编号 161202 评测结果 AAAAAAAAAA
题目名称 [HAOI 2015]树上操作 最终得分 100
用户昵称 GravatarTAT 是否通过 通过
代码语言 C++ 运行时间 0.402 s
提交时间 2015-05-02 15:14:58 内存使用 12.31 MiB
显示代码纯文本
#include<cstdio>
const int maxn=100010;
int st[maxn],en[maxn];
char ch[5000000],*ptr=ch;
long long k[maxn],b[maxn],c[maxn];
int n,m,q[maxn],fa[maxn],siz[maxn],val[maxn],dep[maxn];
int cnt,tot,dfn[maxn],head[maxn],to[maxn<<1],next[maxn<<1];
void ins(int u,int v){
	to[++tot]=v,next[tot]=head[u],head[u]=tot;
	to[++tot]=u,next[tot]=head[v],head[v]=tot;
}
void add1(int i,long long x){
	while(i<=n) k[i]+=x,i+=i&-i;
}
void add2(int i,long long x){
	while(i<=n) b[i]+=x,i+=i&-i;
}
long long query1(int i){
	static long long ret;
	for(ret=0;i>0;i-=i&-i) ret+=k[i];
	return ret;
}
long long query2(int i){
	static long long ret;
	for(ret=0;i>0;i-=i&-i) ret+=b[i];
	return ret;
}
int read(){
	static int f,ch,ret;
	while(*ptr<40) ptr++;
	if(*ptr!=45) f=0,ret=*ptr-48;
	else f=1,ret=0;ptr++;
	while(*ptr>47) ret=ret*10+*ptr++-48;
	if(f) ret=-ret;
	return ret;
}
void dfs(){
	q[1]=1,st[1]=1,en[1]=n+1,dfn[1]=1;
	for(int l=1,r=1;l<=r;){
		int u=q[l++];
		siz[u]=1,c[u]=c[fa[u]]+val[u],dep[u]=dep[fa[u]]+1;
		for(int i=head[u];i;i=next[i])
			if(to[i]!=fa[u])
			    fa[to[i]]=u,q[++r]=to[i];
	}
	for(int i=n;i;i--) siz[fa[q[i]]]+=siz[q[i]];
	for(int i=1;i<=n;i++){
		int now=i+1,last=dfn[i];
		for(int j=head[last];j;j=next[j])
		    if(to[j]!=fa[last]){
				dfn[now]=to[j],st[to[j]]=now;
				now+=siz[to[j]],en[to[j]]=now;
			}
	}
}
int main(){
	freopen("haoi2015_t2.in","r",stdin);
	freopen("haoi2015_t2.out","w",stdout);
	fread(ch,1,5000000,stdin);
	int i,u,v,op;
	long long tmp;
	n=read(),m=read();
	for(i=1;i<=n;i++)
	    val[i]=read();
	for(i=1;i<n;i++)
	    ins(read(),read());
	dfs();
	while(m--){
		op=read();
		switch(op){
			case 1:
				u=read(),v=read();
				add2(st[u],v),add2(en[u],-v);
				break;
			case 2:
				u=read(),v=read();
				tmp=1-dep[u],tmp*=v;
				add1(st[u],v),add1(en[u],-v);
				add2(st[u],tmp),add2(en[u],-tmp);
				break;
			case 3:
				u=read();
				printf("%lld\n",c[u]+query1(st[u])*dep[u]+query2(st[u]));
				break;
		}
	}
	return 0;
}