求调,不成功就成仁
查看原帖
求调,不成功就成仁
1163927
F1NE楼主2024/5/9 20:28
#include<bits/stdc++.h>
#define ll long long
#define mid(x,y) (x+y)>>1
using namespace std;
const int maximum=100009;
int N,M,R,P,cnt=0; 
vector<int> edg[maximum];
int val[maximum],dep[maximum],fa[maximum],son[maximum],
	siz[maximum],id[maximum],dov[maximum],top[maximum];
ll sgt[maximum<<2],laz[maximum<<2];
void dfs1(int x,int f,int d){
	dep[x]=d;
	siz[x]=1;
	fa[x]=f; 
	int maxson=-1,num=edg[x].size();
	for(int i=0,now;i<num;i++){
		now=edg[x][i];
		if(now==f) continue;
		dfs1(now,x,d+1);
		siz[x]+=siz[now];
		if(siz[now]>maxson) son[x]=now,maxson=siz[now];
	}
	return;
}
void dfs2(int x,int topf){
	id[x]=++cnt;
	dov[cnt]=val[x];
	top[x]=topf;
	if(siz[x]==1)return;
	dfs2(son[x],topf);
	int num=edg[x].size();
	for(int i=0,now;i<num;i++){
		now=edg[x][i];
		if(now==fa[x]||now==son[x])continue;
		dfs2(now,now);
	}
	return;
}
void build(int l,int r,int p){//printf("l=%d,r=%d\n",l,r);
	if(l==r){
		sgt[p]=dov[l]%P;return;
	}
	int m=mid(l,r);
	build(l,m,p<<1),build(m+1,r,p<<1|1);
	sgt[p]=(sgt[p<<1]+sgt[p<<1|1])%P;
	return;
}
ll rd(int l,int r,int s,int t,int p){
	if(l<=s&&t<=r)return sgt[p];
	int m=mid(s,t);ll ans=0;
	if(laz[p]){
		(laz[p<<1]+=laz[p])%=P,
		(laz[p<<1|1]+=laz[p])%=P,
		laz[p]=0;
	}
	if(l<=m) (ans+=rd(l,r,s,m,p<<1))%=P;
	if(m<r) (ans+=rd(l,r,m+1,t,p<<1|1))%=P;
	sgt[p]=(sgt[p<<1]+sgt[p<<1|1])%P;
	return ans;
}
void wt(int l,int r,int k,int s,int t,int p){
	if(l<=s&&t<=r){
		(sgt[p]+=k*(t-s+1))%=P;
		(laz[p]+=k)%=P;
		return;
	}
	int m=mid(s,t);
	if(laz[p]){
		(laz[p<<1]+=laz[p])%=P,
		(laz[p<<1|1]+=laz[p])%=P,
		laz[p]=0;
	}
	if(l<=m)wt(l,r,k,s,m,p<<1);
	if(m<r)wt(l,r,k,m+1,t,p<<1|1);
	sgt[p]=(sgt[p<<1]+sgt[p<<1|1])%P;
	return;
}
inline void path_wt(int x,int y,int z){
	//cout<<"yes"<<endl;
	z%=P;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		wt(id[top[x]],id[x],z,1,N,1);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	wt(id[x],id[y],z,1,N,1);
	return;
}
inline ll path_rd(int x,int y){//cout<<"yes"<<endl;
	ll ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		(ans+=rd(id[top[x]],id[x],1,N,1))%=P;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	(ans+=rd(id[x],id[y],1,N,1))%=P;
	return ans;
}
inline void son_wt(int x,int z){//cout<<"yes"<<endl;
	//printf("x=%d,z=%d",x,z);
	z%=P;
	wt(id[x],id[x]+siz[x]-1,z,1,N,1);
	return;
}
inline ll son_rd(int x){//cout<<"yes"<<endl;
	return rd(id[x],id[x]+siz[x]-1,1,N,1);
}
int main(){
	cin>>N>>M>>R>>P;
	for(int i=1;i<=N;i++) scanf("%d",&val[i]);
	for(int i=1,x,y;i<N;i++){
		scanf("%d%d",&x,&y);
		edg[x].push_back(y),
		edg[y].push_back(x);
	}
	dfs1(R,0,1);
	dfs2(R,R);
	build(1,N,1);
	for(int i=1,op,x,y,z;i<=M;i++){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&x,&y,&z);
			path_wt(x,y,z);
		}
		if(op==2){
			scanf("%d%d",&x,&y);
			cout<<path_rd(x,y)<<endl;
		}
		if(op==3){
			scanf("%d%d",&x,&z);
			son_wt(x,z);
		}
		if(op==4){
			scanf("%d",&x);
			cout<<son_rd(x)<<endl;
		}
	}
	return 0;
}

记录
样例没过但是有19pts

2024/5/9 20:28
加载中...