社区讨论

19pts 求助

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

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mhj9ubzu
此快照首次捕获于
2025/11/03 23:04
4 个月前
此快照最后确认于
2025/11/03 23:04
4 个月前
查看原帖
Code:
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,r_id,p,cnt;
int w[N],dep[N],sz[N],fa[N],hs[N],tp[N],nw[N],id[N],lz[N<<2],t[N<<2];
vector<int> g[N]; 
int ls(int o){return o<<1;}
int rs(int o){return o<<1|1;}
void push_up(int o){
	t[o]=(t[o]+t[ls(o)]+t[rs(o)])%p;
}
void f(int s,int e,int o,int x){
	t[o]=(t[o]+1ll*(e-s+1)*x%p)%p;
	lz[o]=(lz[o]+x)%p;
}
void build(int s=1,int e=n,int o=1){
	if (s==e){
		t[o]=nw[s]%p;
		return;
	}
	int mid=(s+e)>>1;
	build(s,mid,ls(o));
	build(mid+1,e,rs(o));
	push_up(o);
}
void push_down(int s,int e,int o){
	if (!lz[o])return;
	int mid=(s+e)>>1;
	f(s,mid,ls(o),lz[o]);
	f(mid+1,e,rs(o),lz[o]);
	lz[o]=0;
}
void update(int l,int r,int x,int s=1,int e=n,int o=1){
	if (l<=s&&e<=r){
		f(s,e,o,x);
		return;
	}
	push_down(s,e,o);
	int mid=(s+e)>>1;
	if (mid>=l)update(l,r,x,s,mid,ls(o));
	if (mid+1<=r)update(l,r,x,mid+1,e,rs(o));
	push_up(o);
}
int query(int l,int r,int s=1,int e=n,int o=1){
	if (l<=s&&e<=r){
		return t[o];
	}
	push_down(s,e,o);
	int mid=(s+e)>>1,res=0;
	if (mid>=l)res=(res+query(l,r,s,mid,ls(o)))%p;
	if (mid+1<=r)res=(res+query(l,r,mid+1,e,rs(o)))%p;
	return res;
}
void update_range(int u,int v,int x){
	while (tp[u]!=tp[v]){
		if (dep[tp[u]]<dep[tp[v]])swap(u,v);
		update(id[tp[u]],id[u],x);
		u=fa[tp[u]];
	}
	if (dep[u]>dep[v])swap(u,v);
	update(id[u],id[v],x);
}
int query_range(int u,int v){
	int res=0;
	while (tp[u]!=tp[v]){
		if (dep[tp[u]]<dep[tp[v]])swap(u,v);
		res=(res+query(id[tp[u]],id[u]))%p;
		u=fa[tp[u]];
	}
	if (dep[u]>dep[v])swap(u,v);
	res=(res+query(id[u],id[v]))%p;
	return res;
}
void update_subtree(int u,int x){
	update(id[u],id[u]+sz[u]-1,x);
}
int query_subtree(int u){
	return query(id[u],id[u]+sz[u]-1);
}
void dfs1(int u,int f){
	int t=-1;
	fa[u]=f;
	dep[u]=dep[f]+1;
	sz[u]=1;
	for (const auto &v:g[u]){
		if (v!=f){
			dfs1(v,u);
			sz[u]+=sz[v];
			if (sz[v]>t){
				t=sz[v];
				hs[u]=v;
			}
		}
	}
}
void dfs2(int u,int top){
	tp[u]=top;
	id[u]=++cnt;
	nw[cnt]=w[u];
	if (hs[u]==0)return;
	dfs2(hs[u],top);
	for (const auto &v:g[u]){
		if (v!=hs[u]&&v!=fa[u]){
			dfs2(v,v);
		}
	}
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m>>r_id>>p;
	for (int i=1;i<=n;i++)cin>>w[i],w[i]%=p;
	for (int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(r_id,0);
	dfs2(r_id,r_id);
	build();
	for (int i=1;i<=m;i++){
		int op,x,y,z;
		cin>>op;
		if (op==1){
			cin>>x>>y>>z;
			update_range(x,y,z);
		}else if (op==2){
			cin>>x>>y;
			cout<<query_range(x,y)<<"\n";
		}else if (op==3){
			cin>>x>>z;
			update_subtree(x,z);
		}else if (op==4){
			cin>>x;
			cout<<query_subtree(x)<<"\n";
		}
	}
	return 0;
}
想知道是自己取模写错了吗,看了半小时没看出来,求助。

回复

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

正在加载回复...