9点RE,1点WA,求助
查看原帖
9点RE,1点WA,求助
53548
Nowed楼主2020/8/6 20:51
#include<cstdio>
#define rr register 
#define ll long long 
using namespace std; 
const ll N=310000; 
const ll M=1240000; 
ll n,m,Summ,R,P; 
ll seg[N],rev[M],size[N],son[N],top[N],dep[N]; 
ll num[N],father[N],Max[N],tot; 
ll first[M],next[M],go[M]; 
struct SegmentTree{
	ll l,r,sum,add; 
	#define l(x) tree[x].l 
	#define r(x) tree[x].r 
	#define sum(x) tree[x].sum
	#define add(x) tree[x].add
}tree[M];
inline void myswap(ll &x,ll &y){x^=y^=x^=y; return;}
inline void in_add(rr ll x,rr ll y){next[++tot]=first[x],first[x]=tot,go[tot]=y;}
inline void insert(rr ll x,rr ll y){in_add(x,y); in_add(y,x);}
inline ll get(){
	rr char c; 
	while ((c=getchar())<'0'||c>'9'); rr ll res=c-'0'; 
	while((c=getchar())>='0'&&c<='9') res=res*10+c-'0'; 
	return res; 
}
inline void write(rr ll x){if (x>9) write(x/10); putchar(x%10+48);}
inline void dfs1(rr ll u,rr ll f){
	rr ll e,v; 
	size[u]=1; 
	father[u]=f; 
	dep[u]=dep[f]+1; 
	for(e=first[u];v=go[e],e;e=next[e])
		if (v!=f){
			dfs1(v,u); 
			size[u]+=size[v]; 
			if (size[v]>size[son[u]]) son[u]=v; 
		}   
	return;                                
}                  
inline void dfs2(rr ll u,rr ll f){
	rr ll e,v; 
	if (son[u]){
		seg[son[u]]=++seg[0]; 
		top[son[u]]=top[u]; 
		rev[seg[0]]=son[u]; 
		dfs2(son[u],u); 
	}
	for(e=first[u];v=go[e],e;e=next[e])
		if(!top[v]){
			seg[v]=++seg[0]; 
			rev[seg[0]]=v; 
			top[v]=v; 
			dfs2(v,u); 
		}
	return; 
}



inline void build(ll p,ll l,ll r){
	l(p)=l,r(p)=r; 
	if (l==r) {sum(p)=num[rev[l]]; return;}
	ll mid=l+r>>1; 
	build(p<<1,l,mid); 
	build(p<<1|1,mid+1,r); 
	sum(p)=sum(p<<1)+sum(p<<1|1); 
	return; 
}
inline void spread(ll p){
	if (add(p)){
		sum(p<<1)+=add(p)*(r(p<<1)-l(p<<1)+1); 
		sum(p<<1|1)+=add(p)*(r(p<<1|1)-l(p<<1|1)+1); 
		add(p<<1)+=add(p); 
		add(p<<1|1)+=add(p); 
		add(p)=0; 
	}
	return; 
}
inline void change(ll p,ll l,ll r,ll d){
	if (l<=l(p)&&r>=r(p)){
		sum(p)+=d*(r(p)-l(p)+1); 
		add(p)+=d; 
		return; 
	}
	spread(p); 
	ll mid=(l(p)+r(p))>>1; 
	if (r<=mid) change(p<<1,l,r,d);
	if (l>mid) change(p<<1|1,l,r,d); 
	sum(p)=sum(p<<1)+sum(p<<1|1); 
	return; 
}
inline ll query(ll p,ll l,ll r){
	if (l<=l(p)&&r>=r(p)) return sum(p); 
	spread(p); 
	ll mid=(l(p)+r(p))>>1; 
	ll val=0; 
	if (r<=mid) val+=query(p<<1,l,r); 
	if (l>mid) val+=query(p<<1|1,l,r); 
	return val; 
}


inline void ask(rr ll x,rr ll y){
	rr ll fx=top[x],fy=top[y]; 
	while(fx!=fy){
		if (dep[fx]<dep[fy]) myswap(x,y),myswap(fx,fy); 
		Summ+=query(1,seg[fx],seg[x]); 
		Summ%=P; 
		x=father[fx]; fx=top[x]; 
	}
	if (dep[x]>dep[y]) myswap(x,y); 
	Summ+=query(1,seg[x],seg[y]); 
	Summ%=P; 
	return;
}
inline void change_range(ll x,ll y,ll z){
	z%=P; 
	ll fx=top[x],fy=top[y]; 
	while(fx!=fy){
		if (dep[fx]<dep[fy]) myswap(x,y),myswap(fx,fy); 
		change(1,seg[fx],seg[x],z); 
		x=father[fx]; fx=top[x]; 
	}
	if (dep[x]>dep[y]) myswap(x,y); 
	change(1,seg[x],seg[y],z); 
	return; 
}
inline void change_son(ll x,ll z){
	change(1,seg[x],seg[x]+size[x]-1,z); 
	return;
}
inline void askson(ll x){
	Summ=query(1,seg[x],seg[x]+size[x]-1); 
	return;
}



int main(){
	rr ll i,j,k,u,v,s1,s2,sr,z; 
	n=get(); m=get(); R=get(); P=get(); 
	for(i=1;i<=n;i++) num[i]=get(); 
	for(i=1;i<n;i++) s1=get(),s2=get(),insert(s1,s2); 
	dfs1(R,0); 
	seg[0]=seg[R]=top[R]=rev[R]=1; 
	dfs2(R,0); 
	build(1,1,seg[0]); 
	for(i=1;i<=m;i++){
		Summ=0; 
		sr=get(); 
		if (sr==1) {
			u=get(),v=get(),z=get(); change_range(u,v,z); 
		} else if (sr==2){
			u=get(),v=get(); ask(u,v); write(Summ); putchar('\n'); 
		} else if (sr==3){
			u=get(),v=get(); change_son(u,v); 
		} else {
			u=get(); askson(u); write(Summ); putchar('\n'); 
		}
	}
	return 0; 
}
2020/8/6 20:51
加载中...