记录编号 |
161202 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[HAOI 2015]树上操作 |
最终得分 |
100 |
用户昵称 |
TAT |
是否通过 |
通过 |
代码语言 |
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;
}