萌新刚学树剖1919810s,WA爆零求条
查看原帖
萌新刚学树剖1919810s,WA爆零求条
639198
Steve_xh楼主2024/1/25 21:00

rt

#include<bits/stdc++.h>
using namespace std;

int n,m,a[100005],cnt,head[100005];
struct EDGE{
	int to,next;
}e[100005<<1|1];
inline void add_edge(int u,int v){
	e[++cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}

int f[100005],sz[100005],son[100005],sgv[100005],seg[100005],tp[100005],segcnt=0;

void dfs1(int now,int fa){
	f[now]=fa;
	sz[now]++; 
	for(int i=head[now];i;i=e[i].next){
		if(e[i].to==fa)
			continue;
		dfs1(e[i].to,now);
		sz[now]+=sz[e[i].to];
		if(sz[e[i].to]>sz[son[now]])
			son[now]=e[i].to;
	}
}
void dfs2(int now,int t){
	tp[now]=t;
	seg[sgv[now]=++segcnt]=now;
	if(!son[now])
		return;
	dfs2(son[now],t);
	for(int i=head[now];i;i=e[i].next)
		if(e[i].to!=f[now]&&e[i].to!=son[now])
			dfs2(e[i].to,e[i].to);
}

struct TREE{
	int l,r,v,tag;
}t[100005<<2|1];
inline void pushup(int x){t[x].v=t[x<<1].v+t[x<<1|1].v;}
inline void addtag(int x,int l,int r,int w){t[x].tag+=w,t[x].v+=w*(r-l+1);}
inline void pushdown(int x){
	if(!t[x].tag)
		return;
	addtag(x<<1,t[x<<1].l,t[x<<1].r,t[x].tag);
	addtag(x<<1|1,t[x<<1|1].l,t[x<<1|1].r,t[x].tag);
	t[x].tag=0;
}
void bt(int x,int l,int r){
	t[x].l=l,t[x].r=r,t[x].tag=0;
	if(l==r){
		t[x].v=a[seg[l]];
		return;
	}
	int mid=(l+r)>>1;
	bt(x<<1,l,mid);
	bt(x<<1|1,mid+1,r);
	pushup(x); 
}
void upd(int x,int l,int r,int w){
	if(l<=t[x].l&&t[x].r<=r)
		return addtag(x,t[x].l,t[x].r,w);
	pushdown(x);
	int mid=(t[x].l+t[x].r)>>1;
	if(l<=mid)
		upd(x<<1,l,r,w);
	if(mid<r)
		upd(x<<1|1,l,r,w);
	pushup(x);
}
int query(int x,int l,int r){
	if(l<=t[x].l&&t[x].r<=r)
		return t[x].v;
	pushdown(x);
	int mid=(t[x].l+t[x].r)>>1,ans=0;
	if(l<=mid)
		ans+=query(x<<1,l,r);
	if(mid<r)
		ans+=query(x<<1|1,l,r);
	return ans;
}

int op3(int x){
	if(x==1)
		return query(1,1,1);
	int ans=0;
	while(x!=1){
		ans+=query(1,sgv[tp[x]],sgv[x]);
		x=f[tp[x]];
	}
	return ans;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",a+i);
	for(int i=1,u,v;i<n;i++){
		scanf("%d%d",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs1(1,1);
	dfs2(1,1);
	bt(1,1,n);
	for(int i=1,op,x,y;i<=m;i++){
		scanf("%d%d",&op,&x);
		if(op==1)
			scanf("%d",&y),upd(1,sgv[x],sgv[x],y);
		else if(op==2)
			scanf("%d",&y),upd(1,sgv[x],sgv[x]+sz[x]-1,y);
		else
			printf("%d\n",op3(x));
	}
	return 0;
}

2024/1/25 21:00
加载中...