萌新刚学OI 玄关求助!!
查看原帖
萌新刚学OI 玄关求助!!
1065252
dfefawefwefefef楼主2025/7/18 20:31
#include<bits/stdc++.h>
#define int long long
const int N=1e5+10;
using namespace std;
int n,m,root,p;
int a[N],b[N];
vector<int> edge[N];
int size[N],fa[N],son[N],dep[N];
int l[N],r[N],top[N],cnt;
struct node{
	int tag,sum;
}data[N*4];
void update(int x){
	data[x].sum=(data[x*2].sum+data[x*2+1].sum)%p;
}
void build(int x,int l,int r){
	if(l==r){
		data[x].sum=b[l]%p;
		data[x].tag=0;
		return ;
	}
	int mid=l+r>>1;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r);
	update(x);
}
void dfs1(int x){
	size[x]=1;
	for(int i=0;i<edge[x].size();i++){
		int y=edge[x][i];
		if(y!=fa[x]){
			fa[y]=x;
			dep[y]=dep[x]+1;
			dfs1(y);
			size[x]+=size[y];
			if(size[y]>size[son[x]]) son[x]=y;
		}
	}
}
void dfs2(int x,int t){
	l[x]=++cnt;
	b[cnt]=a[x];
	top[x]=t;
	if(son[x]) dfs2(son[x],t);
	for(int i=0;i<edge[x].size();i++){
		int y=edge[x][i];
		if(y!=fa[x]&&y!=son[x]) dfs2(y,y);
	}
	r[x]=cnt;
}
void maketag(int x,int k,int L,int R){
	data[x].tag+=k;
	data[x].tag%=k;
	data[x].sum+=k*(R-L+1)%p;
	data[x].sum%=p;
}
void pushdown(int x,int L,int R){
	if(L!=R){
		int mid=L+R>>1;
		maketag(x*2,data[x].tag,L,mid);
		maketag(x*2+1,data[x].tag,L,mid);
		data[x].tag=0;
	}
}
void modify2(int x,int l,int r,int k,int L,int R){
	pushdown(x,L,R);
	if(l<=L&&r<=R){
		maketag(x,k,L,R);
		return ;
	}
	int mid=L+R>>1;
	if(r<=mid) modify2(x*2,l,r,k,L,mid);
	else if(l>=mid+1) modify2(x*2+1,l,r,k,mid+1,R);
	else{
		modify2(x*2,l,r,k,L,mid);
		modify2(x*2+1,l,r,k,mid+1,R);
	}
	update(x);
}
void modify1(int x,int y,int z){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		modify2(1,l[top[x]],l[x],z,1,n);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	modify2(1,l[y],l[x],z,1,n);
}
int find2(int x,int l,int r,int L,int R){
	pushdown(x,L,R);
	if(l<=L&&r>=R) return data[x].sum;
	int mid=L+R>>1;
	if(r<=mid) return find2(x*2,l,r,L,mid);
	else if(l>=mid+1) return find2(x*2+1,l,r,mid+1,R);
	return (find2(x*2,l,r,L,mid)+find2(x*2+1,l,r,mid+1,R))%p;
}
int find1(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans+=find2(1,l[top[x]],l[x],1,n);
		ans%=p;
		x=fa[top[x]];	
	}
	if(dep[x]<dep[y]) swap(x,y);
	ans+=find2(1,l[y],l[x],1,n);
	ans%=p;
	return ans;
}
signed main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	cin.tie(0)->sync_with_stdio(0);
	cin>>n>>m>>root>>p;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<n;i++){
		int x,y;
		cin>>x>>y;
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs1(root);
	dfs2(root,root);
	build(1,1,n);
	while(m--){
		int opt,x,y,z;
		cin>>opt;
		if(opt==1){
			cin>>x>>y>>z;
			modify1(x,y,z);
		}
		else if(opt==2){
			cin>>x>>y;
			cout<<find1(x,y)<<'\n';	
		}
		else if(opt==3){
			cin>>x>>z;
			modify2(1,l[x],r[x],z,1,n);
		}
		else{
			cin>>x;
			cout<<find2(1,l[x],r[x],1,n)<<'\n';
		}
	}
	return 0;
}

没有输出,可能是死循环了吧……

2025/7/18 20:31
加载中...