AC11 求调谢谢
查看原帖
AC11 求调谢谢
541962
L_j_tc楼主2024/9/18 20:53
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int totr;
int i1,i2;
long long i3;
int n,m,r,tot; 
long long a[N],p;
int dfsx[N],dfsk[N];
int sizes[N],dep[N],maxson[N],fa[N],fot[N],endn[N];
int head[N];
struct node{
	int u,v,nex;
}t[N];
struct trees{
	int l,r;
	long long num,add;
}tr[4*N];
void add(int u,int v){
	t[++totr]=(node){u,v,head[u]};
	head[u]=totr;
}
void build(int l,int r,int id){
	tr[id].l=l,tr[id].r=r;
	if(l==r){
		tr[id].num=a[dfsk[l]];
		tr[id].num%=p;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,id*2);
	build(mid+1,r,id*2+1);
	tr[id].num=(tr[2*id].num+tr[2*id+1].num)%p;
//	printf("%d %d %d\n",l,r,tr[id].num);
}
void Size_dfs(int u){
	int maxn=0;
	sizes[u]=1,maxson[u]=0;
	for(int i=head[u];i;i=t[i].nex){
		int v=t[i].v;
		if(v==fa[u]) continue;
		fa[v]=u;
		dep[v]=dep[u]+1;
		Size_dfs(v);
		sizes[u]+=sizes[v];
		if(sizes[v]>maxn){
			maxn=sizes[v];
			maxson[u]=v;
		}
	}
}
void Subdivision(int u,int beg){
	++tot;
	dfsx[tot]=u;
	dfsk[u]=tot;
	if(u==beg) fot[u]=u;
	if(maxson[u]!=0){
		fot[maxson[u]]=beg;
		Subdivision(maxson[u],beg);
		for(int i=head[u];i;i=t[i].nex){
			int v=t[i].v;
			if(v==maxson[u]||v==fa[u]) continue;
			Subdivision(v,v);
		} 
	}
	endn[u]=tot;
}
void pushdown(int id){
	if(tr[id].add!=0){
		tr[2*id].add+=tr[id].add;tr[2*id].add%=p;
		tr[2*id+1].add+=tr[id].add;tr[2*id+1].add%=p;
		tr[2*id].num+=(tr[2*id].r-tr[2*id].l+1)*tr[id].add;tr[2*id].num%=p;
		tr[2*id+1].num+=(tr[2*id+1].r-tr[2*id+1].l+1)*tr[id].add;tr[2*id+1].num%=p;
		tr[id].add=0;
	}
} 
void add_sub(int x,int y,long long num,int id){
	int l=tr[id].l,r=tr[id].r;
	if(x<=l&&y>=r){
		tr[id].num+=(r-l+1)*num;tr[id].num%=p;
		tr[id].add+=num;tr[id].add%=p;
		return;
	}
	pushdown(id);
	int mid=(l+r)>>1;
	if(x<=mid) add_sub(x,y,num,id*2);
	if(y>mid) add_sub(x,y,num,id*2+1);
	tr[id].num=(tr[2*id].num+tr[2*id+1].num)%p;
}
void add_xy(int x,int y,long long num){
	if(fot[x]!=fot[y]){
		if(dep[y]>dep[x]) swap(x,y);
		add_sub(dfsk[fot[x]],dfsk[x],num,1);
		x=fa[fot[x]];
	}
	if(dep[y]>dep[x]) swap(x,y);
	add_sub(dfsk[x],dfsk[y],num,1);
} 
long long find_sub(int x,int y,int id){
	
	int l=tr[id].l,r=tr[id].r,ans=0;
	int mid=(l+r)>>1;
	if(x<=l&&y>=r) return tr[id].num%p;
	/*
	for(int i=1;i<=2*n-1;i++){
		printf("%d ",tr[i].num);
	}
	printf("\n");
	for(int i=1;i<=2*n-1;i++){
		printf("%d ",tr[i].add);
	}
	printf("\n");
	*/ pushdown(id);
	if(x<=mid) ans+=find_sub(x,y,id*2);ans%=p;
	if(y>mid) ans+=find_sub(x,y,id*2+1);ans%=p;
	return ans;
}
long long find_xy(int x,int y){
	long long ans=0;
	while(fot[x]!=fot[y]){
		if(dep[y]>dep[x]) swap(x,y);
		ans+=find_sub(dfsk[fot[x]],dfsk[x],1);
		x=fa[fot[x]];
	} 
	if(dep[y]>dep[x]) swap(x,y);
	ans+=find_sub(dfsk[x],dfsk[y],1);
	ans%=p;
	return ans;
}
void add_subtree(int root,long long num){
	add_sub(dfsk[root],endn[root],num,1);
}
long long find_subtree(int root){
	return find_sub(dfsk[root],endn[root],1)%p;
}
int main(){
	scanf("%d%d%d%lld",&n,&m,&r,&p);
	memset(head,0,sizeof(head));
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(int i=1;i<n;i++){
		scanf("%d%d",&i1,&i2);
		add(i1,i2);add(i2,i1);
	}
	fa[r]=r;
	Size_dfs(r);Subdivision(r,r);build(1,n,1);
	/*
	for(int i=1;i<=n;i++){
		printf("%d %d %d %d %d %d\n",sizes[i],dep[i],fot[i],maxson[i],dfsk[i],endn[i]); 
	}
	for(int i=1;i<=2*n-1;i++){
		printf("%d ",tr[i].num);
	}
	printf("\n");
	for(int i=1;i<=2*n-1;i++){
		printf("%d ",tr[i].add);
	}
	printf("\n");
	*/
	for(int i=1;i<=m;i++){
		scanf("%d",&i1);
		if(i1==1){
			scanf("%d%d%lld",&i1,&i2,&i3);
			add_xy(i1,i2,i3);
		}
		else if(i1==2){
			scanf("%d%d",&i1,&i2);
			printf("%lld\n",find_xy(i1,i2));
		}
		else if(i1==3){
			scanf("%d%lld",&i1,&i3);
			//printf("%d %d\n",dfsk[i1],endn[i1]);
			add_subtree(i1,i3); 
			
		}
		else{
			scanf("%d",&i1);
			printf("%lld\n",find_subtree(i1));
		}
		/*
		for(int i=1;i<=2*n-1;i++){
			printf("%d ",tr[i].num);
		}
		printf("\n");
		for(int i=1;i<=2*n-1;i++){
			printf("%d ",tr[i].add);
		}
		printf("\n");
		*/ 
	}
	return 0;
}
2024/9/18 20:53
加载中...