社区讨论

求调

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

讨论操作

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

当前回复
6 条
当前快照
1 份
快照标识符
@mhj1yir2
此快照首次捕获于
2025/11/03 19:24
4 个月前
此快照最后确认于
2025/11/03 19:24
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define lx x<<1
#define rx (x<<1)+1
using namespace std;
const int N=1e5+10,M=2e5+10;
#define int long long
int h[N],nx[M],to[M];
int vl[N];
int dfn[N],rhk[N];
int size[N],top[N];
int son[N],deep[N];
int f[N];
int n,k,root,mod,idx=1,tnum;
int tree[4*N];
int lz[4*N],l[4*N],r[4*N];

void egde_add(int u,int v)
{
	nx[idx]=h[u];
	to[idx]=v;
	h[u]=idx++;
}

void dfs1(int u,int fa)
{
	deep[u]=deep[fa]+1;
	size[u]=1;
	int mx=0;
	for(int i=h[u];i;i=nx[i])
	{
		int v=to[i];
		if(fa==v) continue;
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>mx)
		{
			mx=size[v];
			son[u]=v;
		}
	}
}

void dfs2(int u,int fa,int topf)
{
	f[u]=fa;
	top[u]=topf;
	dfn[u]=++tnum;
	rhk[dfn[u]]=u;
	if(son[u]) dfs2(son[u],u,topf);
	for(int i=h[u];i;i=nx[i])
	{
		int v=to[i];
		if(fa==v) continue;
		if(v==son[u]) continue;
		dfs2(v,u,v);
	}
//	cout<<son[u]<<" "<<u<<endl;
}

void push_up(int x)
{
	tree[x]=tree[lx]+tree[rx];
}

void push_down(int x)
{
	lz[lx]+=lz[x];
	lz[rx]+=lz[x];
	tree[lx]+=lz[lx]*(r[lx]-l[lx]+1);
	tree[rx]+=lz[rx]*(r[rx]-l[rx]+1);
	lz[x]=0;
}

void build(int tl,int tr,int x)
{
	l[x]=tl,r[x]=tr;
	if(tl==tr)
	{
//		cout<<x<<" ";
		tree[x]=vl[rhk[tl]];
		return;
	}
	int mid=(tl+tr)>>1;
	build(tl,mid,lx);
	build(mid+1,tr,rx);
	push_up(x);
}

void add(int dl,int dr,int x,int num)
{
	if(dl<=l[x] && dr>=r[x])
	{
		lz[x]=num;
		tree[x]+=num*(r[x]-l[x]+1);
		return;
	}
	push_down(x);
	int mid=(l[x]+r[x])>>1;
	if(dl<=mid) add(dl,dr,lx,num);
	if(dr>mid) add(dl,dr,rx,num);
	push_up(x);
}

int query(int dl,int dr,int x)
{
	if(dl<=l[x] && dr>=r[x])
	{
		return tree[x];
	}
	push_down(x);
	int ans=0;
	int mid=(l[x]+r[x])>>1;
	if(dl<=mid) ans+=query(dl,dr,lx);
	if(dr>mid) ans+=query(dl,dr,rx);
	return ans;
}

void change(int x,int y,int z)
{
//	cout<<query(dfn[5],dfn[5],1);
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		add(dfn[top[x]],dfn[x],1,z);
		x=f[top[x]];
	}
	cout<<query(dfn[5],dfn[5],1)<<endl;
	if(x>y) add(dfn[y],dfn[x],1,z);
	else add(dfn[x],dfn[y],1,z);
}

int ask(int x,int y)
{
	int res=0;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		res+=query(dfn[top[x]],dfn[x],1);
//		cout<<x<<" "<<top[x]<<endl;
		x=f[top[x]];
	}
//	cout<<res<<" ";
//	cout<<x<<" "<<y<<" ";
	if(x>y) res+=query(dfn[y],dfn[x],1);
	else res+=query(dfn[x],dfn[y],1);
	return res;
}

void solve(int t)
{
	int x,y,z;
	if(t==1)
	{
		cin>>x>>y>>z;
		change(x,y,z);
	}
	
	if(t==2)
	{
		cin>>x>>y;
		cout<<ask(x,y)<<"\n";
	}
	
	if(t==3)
	{
		cin>>x>>z;
		add(dfn[x],dfn[x]+size[x]-1,1,z);
	}
	
	if(t==4)
	{
		cin>>x;
//		cout<<query(dfn[x],dfn[x]+size[x]-1,1)<<"\n";
	}
}

signed main(){
	cin>>n>>k>>root>>mod;
	for(int i=1;i<=n;i++) cin>>vl[i];
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		egde_add(u,v);
		egde_add(v,u);
	}
	dfs1(root,root);
	dfs2(root,root,root);
	build(1,tnum,1);
	int t;
	for(int i=1;i<=k;i++) cin>>t,solve(t);
}

回复

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

正在加载回复...