蒟蒻求助-20分
查看原帖
蒟蒻求助-20分
159959
虫洞吞噬者楼主2021/12/18 21:39

RT,刚开始我觉得可能是取模做错了,修改了以后i仿佛没有改变?会不会是取模太少了??

求大佬指教

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 1001000
#define int long long
int n,m,cnt,s,mod,tot;
int num[N],dep[N],fa[N],dfn[N],tp[N],rk[N],siz[N],son[N],head[N];
struct Edge{
	int nxt,to;
}edge[N*2];
struct Tree{
	int l,r,lz,sum;
}tree[N*4];
void add(int from,int to)
{
	edge[++cnt].nxt=head[from];
	edge[cnt].to=to;
	head[from]=cnt;
}
void dfs1(int s,int pre)
{
	fa[s]=pre;
	siz[s]=1;
	dep[s]=dep[pre]+1;
	for(int i=head[s];i;i=edge[i].nxt)
	{
		int nxt=edge[i].to;
		if(nxt==pre)continue;
		dfs1(nxt,s);
		siz[s]+=siz[nxt];
		if(siz[nxt]>siz[son[s]])son[s]=nxt;
	}
}
void dfs2(int s,int top)
{
	tp[s]=top;
	dfn[s]=++tot;
	rk[tot]=s;
	if(son[s])dfs2(son[s],top);
	for(int i=head[s];i;i=edge[i].nxt)
	{
		int nxt=edge[i].to;
		if(nxt==fa[s]||nxt==son[s])continue;
		dfs2(nxt,nxt);
	}
}
void pushup(int id)
{
	tree[id].sum=(tree[id*2].sum+tree[id*2+1].sum)%mod;
}
void pushdown(int id)
{
	if(!tree[id].lz)return;
	int mid=(tree[id].l+tree[id].r)/2;
	tree[id*2].lz=(tree[id].lz+tree[id*2].lz)%mod;
	tree[id*2+1].lz=(tree[id].lz+tree[id*2+1].lz)%mod;
	tree[id*2].sum=((mid-tree[id].l+1)*tree[id].lz%mod+tree[id*2].sum)%mod;
	tree[id*2+1].sum=((tree[id].r-mid)*tree[id].lz%mod+tree[id*2+1].sum)%mod;
	tree[id].lz=0;
}
void build(int id,int l,int r)
{
	tree[id].l=l;tree[id].r=r;
	if(l==r)
	{
		tree[id].sum=num[rk[l]]%mod;
		return;
	}
	int mid=(l+r)/2;
	build(id*2,l,mid);
	build(id*2+1,mid+1,r);
	pushup(id);
}
void add(int id,int l,int r,int k)
{
	if(l<=tree[id].l&&tree[id].r<=r)
	{
		tree[id].lz=(k+tree[id].lz)%mod;
		tree[id].sum=((tree[id].r-tree[id].l+1)*k%mod+tree[id].sum)%mod;
		return;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(l<=mid)add(id*2,l,r,k);
	if(r>mid)add(id*2+1,l,r,k);
	pushup(id);
}
int find(int id,int l,int r)
{
	if(l<=tree[id].l&&tree[id].r<=r)return tree[id].sum;
	pushdown(id);
	int mid=(tree[id].l+tree[id].r)/2;
	int sum=0;
	if(l<=mid)sum=(find(id*2,l,r)+sum)%mod;
	if(r>mid)sum=(find(id*2+1,l,r)+sum)%mod;
	return sum;
}
void addf(int x,int y,int k)
{
	while(tp[x]!=tp[y])
	{
		if(dep[tp[x]]<dep[tp[y]])swap(x,y);
		add(1,dfn[tp[x]],dfn[x],k);
		x=tp[x];
		x=fa[x];
	}
	if(dep[x]<dep[y])swap(x,y);
	add(1,dfn[y],dfn[x],k);
}
int sumf(int x,int y)
{
	int sum=0;
	while(tp[x]!=tp[y])
	{
		if(dep[tp[x]]<dep[tp[y]])swap(x,y);
		sum=(find(1,dfn[tp[x]],dfn[x])+sum)%mod;
		x=tp[x];
		x=fa[x];
	}
	if(dep[x]<dep[y])swap(x,y);
	sum=(sum+find(1,dfn[y],dfn[x]))%mod;
	return sum;
}
signed main()
{
	scanf("%lld%lld%lld%lld",&n,&m,&s,&mod);
	for(int i=1;i<=n;++i)scanf("%lld",&num[i]);
	for(int i=1;i<n;++i)
	{
		int x,y;
		scanf("%lld%lld",&x,&y);
		add(x,y);
		add(y,x);
	}
	dfs1(s,0);
	dfs2(s,s);
	build(1,1,tot);
	for(int i=1;i<=m;++i)
	{
		int x,y,z,k;
		scanf("%lld",&k);
		if(k==1)
		{
			scanf("%lld%lld%lld",&x,&y,&z);
			addf(x,y,z);
		}
		else if(k==2)
		{
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",sumf(x,y));
		}
		else if(k==3)
		{
			scanf("%lld%lld",&x,&z);
			add(1,dfn[x],dfn[x]+siz[x]-1,z);
		}
		else
		{
			scanf("%lld",&x);
			printf("%lld\n",find(1,dfn[x],dfn[x]+siz[x]-1));
		}
	}
	return 0;
}
2021/12/18 21:39
加载中...