30pts求助
查看原帖
30pts求助
387037
MrSWdAxiv楼主2024/7/15 09:45
#include<bits/stdc++.h>
#define int long long
#define MAX 100005
#define inf 0x7f7f7f7f
using namespace std;
int N,M,a[MAX],cnt,head[MAX],fa[MAX],siz[MAX];
int dep[MAX],son[MAX],top[MAX],tot;
int dfn[MAX],rnk[MAX],tree[MAX*4],lazy[MAX];
struct MRS{
	int to,next;
}edge[MAX*2];
void add(int u,int v){
	cnt++;
	edge[cnt].to=v;
	edge[cnt].next=head[u];
	head[u]=cnt;
}
void dfs1(int u,int f){
	fa[u]=f;
	siz[u]=1;
	for(int i=head[u];i;i=edge[i].next){
		int v=edge[i].to;
		if(v==f)continue;
		dep[v]=dep[u]+1;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[u]>siz[son[u]])son[u]=v;
	}
}
void dfs2(int u,int t){
	top[u]=t;
	dfn[u]=++tot;
	rnk[tot]=u;
	if(son[u])dfs2(son[u],t);
	for(int i=head[u];i;i=edge[i].next){
		int v=edge[i].to;
		if(v==fa[u]||v==son[u])continue;
		dfs2(v,v);
	}
}
void ADD(int k,int l,int r,int v){
	tree[k]+=(r-l+1)*v;
	lazy[k]+=v;
}
void pushdown(int k,int l,int r){
	if(!lazy[k])return;
	int mid=(l+r)>>1;
	ADD(k*2,l,mid,lazy[k]);
	ADD(k*2+1,mid+1,r,lazy[k]);
	lazy[k]=0;
}
void build(int k,int l,int r){
	if(l==r){
		tree[k]=a[rnk[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(k*2,l,mid);
	build(k*2+1,mid+1,r);
	tree[k]=tree[k*2]+tree[k*2+1];
}
void change(int k,int l,int r,int x,int y,int v){
	if(l>=x&&r<=y){
		tree[k]+=(r-l+1)*v;
		lazy[k]+=v;
		return;
	}
	pushdown(k,l,r);
	int mid=(l+r)>>1;
	if(x<=mid)change(k*2,l,mid,x,y,v);
	if(y>mid)change(k*2+1,mid+1,r,x,y,v);
	tree[k]=tree[k*2]+tree[k*2+1];
}
int query(int k,int l,int r,int x,int y){
	if(l>=x&&r<=y)return tree[k];
	pushdown(k,l,r);
	int mid=(l+r)>>1,res=0;
	if(x<=mid)res+=query(k*2,l,mid,x,y);
	if(y>mid)res+=query(k*2+1,mid+1,r,x,y);
	return res;
}
int ask(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		ans+=query(1,1,N,dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	ans+=query(1,1,N,dfn[x],dfn[y]);
	return ans;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>N>>M;
	for(int i=1;i<=N;i++)cin>>a[i];
	for(int i=1,x,y;i<=N-1;i++){
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,N);
	for(int i=1,op,x,y;i<=M;i++){
		cin>>op;
		if(op==1)cin>>x>>y,change(1,1,N,dfn[x],dfn[x],y);
		else if(op==2)cin>>x>>y,change(1,1,N,dfn[x],dfn[x]+siz[x]-1,y);
		else cin>>x,cout<<ask(1,x)<<'\n';
	}
	return 0;
}
/*
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
*/
2024/7/15 09:45
加载中...