#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const int maxn=100010;
int n,m;
int fir[maxn],nex[maxn*2];
int u[maxn*2],v[maxn*2],w[maxn*2];
vector<int> e[maxn];
int fa[maxn],dep[maxn],size[maxn],son[maxn];
void dfs1(int i,int deep){
dep[i]=deep;
size[i]=1;
// for(int j=0;j<e[i].size();j++) if(e[i][j]==2) cout<<i<<endl;
for(int j=0;j<e[i].size();j++){
int to=e[i][j];
//if(e[i][j]==2) cout<<i<<endl;
if(to==fa[i]) continue;
fa[to]=i;
dfs1(to,deep+1);
size[i]+=size[to];
if(size[son[i]]<size[to])
son[i]=to;
}
return;
}
int dfn[maxn],top[maxn],tot,re[maxn];
int so[maxn][2];
void dfs2(int i,int tp){
top[i]=tp;
dfn[i]=++tot;
re[tot]=i;
so[i][0]=tot;
if(son[i]) dfs2(son[i],tp);
for(int j=0;j<e[i].size();j++){
int to=e[i][j];
if(to==son[i]||to==fa[i]) continue;
dfs2(to,to);
}
so[i][1]=tot;
return;
}
#define ll long long
struct tr{
int l,r;
ll sum,add;
}t[maxn*8];
void up(int i){t[i].sum=t[i<<1].sum+t[i<<1|1].sum;return;}
void down(int i){
int l=t[i].l,r=t[i].r;
int mid=(l+r)>>1;
t[i<<1].add+=t[i].add;
t[i<<1].sum+=t[i].add*(mid-l+1);
t[i<<1|1].add+=t[i].add;
t[i<<1|1].sum+=t[i].add*(r-mid);
t[i].add=0;
return;
}
void built(int i,int l,int r){
t[i].l=l;t[i].r=r;
if(l==r){
t[i].sum=w[re[l]];
return;
}
int mid=(l+r)>>1;
built(i<<1,l,mid);
built(i<<1|1,mid+1,r);
up(i);
return;
}
void cha(int i,int l,int r,int L,int R,ll num){
if(L<=l&&R>=r){
t[i].sum+=(r-l+1)*num;
t[i].add+=num;
//cout<<i<<" "<<L<<" "<<R<<" "<<t[i].add<<endl;
return;
}
down(i);
int mid=(l+r)>>1;
if(L<=mid) cha(i<<1,l,mid,L,R,num);
if(R>mid) cha(i<<1|1,mid+1,r,L,R,num);
up(i);
return;
}
ll ask(int i,int l,int r,int L,int R){
if(L<=l&&R>=r) return t[i].sum;
down(i);
int mid=(l+r)>>1;
ll ans=0;
if(L<=mid) ans+=ask(i<<1,l,mid,L,R);
if(R>mid) ans+=ask(i<<1|1,mid+1,r,L,R);
return ans;
}
int main(){
freopen("1.txt","r",stdin);
//freopen("12.txt","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&w[i]);
for(int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
e[a].push_back(b);
e[b].push_back(a);
}
dfs1(1,0);
dfs2(1,1);
built(1,1,n);
for(int i=1;i<=m;i++){
int op,x,a;
scanf("%d%d",&op,&x);
if(op==1){
scanf("%d",&a);
cha(1,1,n,dfn[x],dfn[x],a);
}
if(op==2){
scanf("%d",&a);
cha(1,1,n,so[x][0],so[x][1],a);
}
if(op==3){
ll ans=0;
do{
ans+=ask(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}while(x);
printf("%lld\n",ans);
}
}
return 0;
}
这一份是全RE了,但下载数据在本机跑没出锅
我把第三种操作改成
if(op==3){
ll ans=0;
int y=1;
while(top[x]!=1){
ans+=ask(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
ans+=ask(1,1,n,dfn[y],dfn[x]);
printf("%lld\n",ans);
}
就过了