为什么会RE,只有第11个点 AC
查看原帖
为什么会RE,只有第11个点 AC
1024529
sszxyyds楼主2024/3/25 09:11
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,r,p;
int to[200009],nxt[200009],hd[200009],w[200009],nw[200009];
int a[200009<<2],laz[200009<<2];
int son[200009],id[200009],fa[200009],dep[200009],siz[200009],top[200009];
int sum=0,cnt,cnt2;
void add(int x,int y){
	to[++cnt2]=y;
	nxt[cnt2]=hd[x];
	hd[x]=cnt2;
}
void build(int rt,int l,int r){
	if(l==r){
		a[rt]=nw[l];
		a[rt]%=p;
		return;
	}
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	a[rt]=(a[rt<<1]+a[rt<<1|1])%p;
}
void pushdown(int rt,int len){
	laz[rt<<1]+=laz[rt];
	laz[rt<<1|1]+=laz[rt];
	a[rt<<1]+=(len-(len>>1))*laz[rt];
	a[rt<<1|1]+=(len>>1)*laz[rt];
	a[rt<<1]%=p;a[rt<<1|1]%=p;
	laz[rt]=0;//important
}
void query(int rt,int l,int r,int x,int y){
	if(x<=l&&y>=r){
		sum+=a[rt];
		sum%=p;
		return ;
	}
	else{
		if(laz[rt]){
			pushdown(rt,r-l+1);
		}
		int mid=(l+r)>>1;
		if(x<=mid){
			query(rt<<1,l,mid,x,y);
		}//左区间是否被涉及 
		if(y>mid){
			query(rt<<1|1,mid+1,r,x,y);
		}
	}
}
void update(int rt,int l,int r,int x,int y,int k){
	if(x<=l&&y>=r){
		laz[rt]+=k;
		a[rt]+=(r-l+1)*k;
	}else{
		if(laz[rt]){
			pushdown(rt,r-l+1);
		}
		int mid=(l+r)>>1;
		if(x<=mid){
			update(rt<<1,l,mid,x,y,k);
		}//左区间是否被涉及 
		if(y>mid){
			update(rt<<1|1,mid+1,r,x,y,k);
		}
		a[rt]=(a[rt<<1]+a[rt<<1|1])%p;//每个被访问结点都要更新 
	}
}
int range(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}//选深度更深的调整 
		sum=0;
		query(1,1,n,id[top[x]],id[x]);
		ans+=sum;ans%=p;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]){
		swap(x,y);
	}
	sum=0;
	query(1,1,n,id[x],id[y]);
	ans+=sum;
	return ans%p;
}
void change(int x,int y,int k){
	k%=p;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		update(1,1,n,id[top[x]],id[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]){
		swap(x,y);
	}
	update(1,1,n,id[x],id[y],k);
}
int qson(int x){
	sum=0;
	query(1,1,n,id[x],id[x]+siz[x]-1);
	return sum; 
}
int upson(int x,int k){
	update(1,1,n,id[x],id[x]+siz[x]-1,k);
}
void dfs1(int x,int f,int deep){
	dep[x]=deep;
	fa[x]=f;
	siz[x]=1;
	int mson=-1;
	for(int i=hd[x];i;i=nxt[i]){
		int y=to[i];
		if(y==f){
			continue;
		}
		dfs1(y,x,deep+1);
		siz[x]+=siz[y];
		if(siz[y]>mson){
			son[x]=y;
			mson=siz[y];
		}
	}
}
void dfs2(int x,int topf){
	id[x]=++cnt;
	nw[cnt]=w[x];//x是当前节点
	top[x]=topf;
	if(!son[x]){
		return ;
	} 
	dfs2(son[x],topf);
	for(int i=hd[x];i;i=nxt[i]){
		int y=to[i];
		if(y==fa[x]||y==son[x]){
			continue;
		}
		dfs2(y,y);
		//每个轻儿子就是 新链的顶点 
	}
}
signed main(){
	scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
	for(int i=1;i<=n;i++){
		scanf("%lld",&w[i]);
	}
	for(int i=1;i<n;i++){
		int a,b;
		scanf("%lld%lld",&a,&b);
		add(a,b);add(b,a);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	build(1,1,n);
	while(m--){
		int x,y,z,op;
		scanf("%lld",&op);
		if(op==1){
			scanf("%lld%lld%lld",&x,&y,&z);
			change(x,y,z);
		}
		else if(op==2){
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",range(x,y));
		}
		else if(op==3){
			scanf("%lld%lld",&x,&y);
			upson(x,y);
		}else{
			scanf("%lld",&x);
			printf("%lld\n",qson(x));
		}
	}
	return 0;
}

样例可以过

2024/3/25 09:11
加载中...