社区讨论

只AC#10其他都RE了 而且本地能跑

P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mi8kxk68
此快照首次捕获于
2025/11/21 16:09
4 个月前
此快照最后确认于
2025/11/21 17:53
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MS=1e6+5;
int n,m,r,mod,a[MS],w[MS],tree[MS*4],tag[MS*4];
int num;
int son[MS]/*重儿子*/,sz[MS]/*子树大小*/,dep[MS]/*深度*/,dfn[MS],fa[MS],top[MS]/*重链顶*/,cnt;
vector<int> e[MS];
void dfs1(int u,int f){
	sz[u]=1;
	fa[u]=f;
	for(int i=0;i<e[u].size();i++){
		int v=e[u][i];
		if(v==f)continue;
		dep[v]=dep[u]+1;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]])
			son[u]=v;
	}
}
void dfs2(int u,int f){
	dfn[u]=++cnt;
	w[dfn[u]]=a[u];
	if(top[f]==0||son[f]!=u)top[u]=u;
	else top[u]=top[f];
	if(son[u]==0)return;
	dfs2(son[u],u);
	for(int i=0;i<e[u].size();i++){
		int v=e[u][i];
		if(v==f)continue;
		if(v==son[u])continue;
		dfs2(v,u);
	}
}
void build(int p,int l,int r){
	if(l==r){
		tree[p]=w[l]%mod;
		return;
	}
	int mid=(l+r)/2;
	build(p+p,l,mid);
	build(p+p+1,mid+1,r);
	tree[p]=(tree[p+p]+tree[p+p+1])%mod;
}
void pushdown(int p,int l,int r){
//	printf("%d %d %d %d\n",p,l,r,tag[p]);
	if(l!=r){
		int mid=(r+l)/2;
		tree[p+p]=(tree[p+p]+tag[p]*(mid-l+1))%mod;
		tree[p+p+1]=(tree[p+p+1]+tag[p]*(r-mid))%mod;
		tag[p+p]=(tag[p+p]+tag[p])%mod;
		tag[p+p+1]=(tag[p+p+1]+tag[p])%mod;
	}
	tag[p]=0;
}
void change(int p,int l,int r,int x,int y,int z){
//	if(p>1e6){cout<<"Q";return;}
	if(x>y)return;
	if(tag[p])pushdown(p,l,r);
	if(l==x&&r==y){
		tree[p]=(tree[p]+(r-l+1)*z)%mod;
		tag[p]=(tag[p]+z)%mod;
		return;
	}
	int mid=(l+r)/2;
	if(y<=mid)change(p+p,l,mid,x,y,z);
	else if(x>mid)change(p+p+1,mid+1,r,x,y,z);
	else{
		change(p+p,l,mid,x,mid,z);
		change(p+p+1,mid+1,r,mid+1,y,z);
	}
	tree[p]=(tree[p+p]+tree[p+p+1])%mod;
}
int query(int p,int l,int r,int x,int y){
//	if(p>1e6){cout<<"Q";return 0;}
	if(x>y)return 0;
	if(tag[p])pushdown(p,l,r);
	if(l==x&&r==y){
		return tree[p];
	}
	int mid=(l+r)/2;
	if(y<=mid)return query(p+p,l,mid,x,y);
	else if(x>mid)query(p+p+1,mid+1,r,x,y);
	else return (query(p+p,l,mid,x,mid)+query(p+p+1,mid+1,r,mid+1,y))%mod;
}
signed main(){
/*	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	mod=1e9;
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt,x,y,z;
		scanf("%d%d%d",&opt,&x,&y);
		if(opt==1){
			scanf("%d",&z);
			change(1,1,n,x,y,z);
		}else printf("%d\n",query(1,1,n,x,y));
	}
*/	scanf("%lld%lld%lld%lld",&n,&m,&r,&mod);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]),a[i]%=mod;
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%lld%lld",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dep[r]=1;
//	debug
	dfs1(r,0);
//	for(int i=1;i<=n;i++)
//		cout<<son[i]<<endl;
//	debug
	dfs2(r,0);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt,x,y,z;
		scanf("%lld%lld",&opt,&x);
		if(opt==1){
			scanf("%lld%lld",&y,&z);
			while(top[x]!=top[y]){
				if(dep[top[x]]<dep[top[y]])swap(x,y);
				change(1,1,n,dfn[top[x]],dfn[x],z);
				x=fa[top[x]];
			}
			if(dfn[x]<dfn[y])swap(x,y);
			change(1,1,n,dfn[y],dfn[x],z);
		}
		if(opt==2){
			scanf("%lld",&y);
			int res=0;
			while(top[x]!=top[y]){
				if(dep[top[x]]<dep[top[y]])swap(x,y);
				res=(res+query(1,1,n,dfn[top[x]],dfn[x]))%mod;
				x=fa[top[x]];
			}
			if(dfn[x]<dfn[y])swap(x,y);
			res=(res+query(1,1,n,dfn[y],dfn[x]))%mod;
			printf("%lld\n",res);
		}
		if(opt==3){
			scanf("%lld",&z);
			change(1,1,n,dfn[x],dfn[x]+sz[x]-1,z);
		}
		if(opt==4){
			printf("%lld\n",query(1,1,n,dfn[x],dfn[x]+sz[x]-1));
		}
	}
	return 0; 
}
/*
 8 100 1 10000
 0 0 0 0 0 0 0 0
 1 2 2 3 3 4 2 5 1 6 6 7 6 8
 
*/

回复

1 条回复,欢迎继续交流。

正在加载回复...