树剖代码求助
查看原帖
树剖代码求助
760171
Binah_cyc楼主2024/1/18 21:49

rt,过不了样例求助

#include <bits/stdc++.h>
using namespace std;
//#define int long long
const int N=1e5+5;
int mod;
int n,m,r,sum[N];
int f[N],son[N],sze[N],deep[N],id[N],top[N],a[N],cnt;
int tot,head[N];
struct Node
{
	int nxt,to;
} edge[N<<1];
struct SegementTree
{
	int l,r;
	int ans,add;
} t[N<<2];
void add(int x,int y)
{
	edge[++tot]=(Node)
	{
		head[x],y
	};
	head[x]=tot;
}
void dfs1(int now,int fa,int dep)
{
	deep[now]=dep;
	f[now]=fa;
	sze[now]=1;
	int t=-1;
	for(int i=head[now]; i; i=edge[i].nxt)
	{
		if(edge[i].to==fa) continue;
		dfs1(edge[i].to,now,dep+1);
		sze[now]+=sze[edge[i].to];
		if(sze[edge[i].to]>t) t=sze[edge[i].to],son[now]=edge[i].to;
	}
}
void dfs2(int now,int ffa)
{
	id[now]=++cnt;
	a[cnt]=sum[now];
	top[cnt]=ffa;
	if(!son[now]) return ;
	dfs2(son[now],ffa);
	for(int i=head[now]; i; i=edge[i].nxt)
	{
		if(edge[i].to==son[now]||edge[i].to==f[now]) continue;
		dfs2(edge[i].to,edge[i].to);
	}
}
void build(int l,int r,int p)
{
	t[p].l=l;
	t[p].r=r;
	if(l==r)
	{
		t[p].ans=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,p*2);
	build(mid+1,r,p*2+1);
	t[p].ans=t[p*2].ans+t[p*2+1].ans;
	return ;
}
void spread(int p)
{
	if(t[p].add)
	{
		t[p*2].ans=(t[p*2].ans+(t[p*2].r-t[p*2].l+1)*t[p].add)%mod;
		t[p*2+1].ans=(t[p*2+1].ans+(t[p*2+1].r-t[p*2+1].l+1)*t[p].add)%mod;
		t[p*2].add+=t[p].add;
		t[p*2+1].add+=t[p].add;
		t[p].add=0;
	}
	return ;
}
void change(int l,int r,int k,int p)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		t[p].ans=(t[p].ans+(t[p].r-t[p].l+1)*k)%mod;
		t[p].add+=k;
		return ;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) change(l,r,k,p*2);
	if(r>mid) change(l,r,k,p*2+1);
	t[p].ans=t[p*2].ans+t[p*2+1].ans;
	return ;
}
int ask(int l,int r,int p)
{
	if(l<=t[p].l&&t[p].r<=r) return t[p].ans;
	spread(p);
	int sum=0,mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) sum+=ask(l,r,p*2);
	if(r>mid) sum+=ask(l,r,p*2+1);
	return sum;
}
void changeroad(int x,int y,int num)
{
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		change(id[top[x]],id[x],num,1);
		x=f[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	change(id[x],id[y],num,1);
}
int askroad(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		ans=(ans+ask(id[top[x]],id[x],1))%mod;
		x=f[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	return (ans+ask(id[x],id[y],1))%mod;
}
void changetree(int x,int num)
{
	change(id[x],id[x]+sze[x]-1,num,1);
	return ;
}
int asktree(int x)
{
	return ask(id[x],id[x]+sze[x]-1,1);
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m>>r>>mod;
	int x,y;
	for(int i=1; i<=n; i++) cin>>sum[i];
	for(int i=1; i<n; i++)
	{
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	build(1,n,1);
	while(m--)
	{
		int op,x,y,z;
		cin>>op;
		if(op==1)
		{
			cin>>x>>y>>z;
			changeroad(x,y,z%mod);
		}
		else if(op==2)
		{
			cin>>x>>y;
			cout<<askroad(x,y)<<endl;
		}
		else if(op==3)
		{
			cin>>x>>z;
			changetree(x,z);
		}
		else if(op==4)
		{
			cin>>x;
			cout<<asktree(x)<<endl;
		}
//		cout<<askroad(1,1)<<' '<<askroad(3,3)<<' '<<askroad(4,4)<<' '<<askroad(5,5)<<" "<<endl;
	}
//	for(int i=1;i<=n;i++) cout<<i<<' '<<"deep:"<<deep[id[i]]<<' '<<"f:"<<f[id[i]]<<' '<<"id:"<<id[i]<<' '<<"son:"<<son[id[i]]<<' '<<"sum:"<<sum[id[i]]<<' '<<"sze:"<<sze[id[i]]<<' '<<"top:"<<top[id[i]]<<'\n';
	return 0;
}
2024/1/18 21:49
加载中...