树剖过不了样例求助
查看原帖
树剖过不了样例求助
715233
Dino_chx楼主2023/8/13 10:31

这个是跟着日报学的树剖,但是不知道为什么过不了样例,求助qwq

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+7;
vector<int> e[N];
int n,m,root,P,a[N],fa[N],d[N],siz[N],son[N],rk[N],top[N],dfn[N],thistime;
struct Segment_Tree
{
	struct maintain
	{
		int l,r;
		ll sum,tag;
	}tree[N<<2];
	void pushup(int x)
	{
		tree[x].sum=(tree[x<<1].sum+tree[x<<1|1].sum)%P;
		return;
	}
	void build(int x,int l,int r)
	{
		tree[x]={l,r};
		if(l==r)
		{
			tree[x].sum=a[rk[l]]%P;
			return;
		}
		int mid=l+r>>1;
		build(x<<1,l,mid);
		build(x<<1|1,mid+1,r);
		pushup(x);
		return;
	}
	void pushdown(int x)
	{
		maintain &rt=tree[x],&ls=tree[x<<1],&rs=tree[x<<1|1];
		if(rt.tag)
		{
			ls.tag=(ls.tag+rt.tag)%P;
			rs.tag=(rs.tag+rt.tag)%P;
			ls.sum=(ls.sum+(ls.r-ls.l+1)*rt.tag%P)%P;
			rs.sum=(ls.sum+(rs.r-rs.l+1)*rt.tag%P)%P;
			rt.tag=0;
		}
		return;
	}
	void update(int x,int l,int r,int k)
	{
		if(l<=tree[x].l&&r>=tree[x].r)
		{
			tree[x].sum=(tree[x].sum+(tree[x].r-tree[x].l+1)*k%P)%P;
			tree[x].tag=(tree[x].tag+k)%P;
			return;
		}
		pushdown(x);
		int mid=tree[x].l+tree[x].r>>1;
		if(l<=mid)
			update(x<<1,l,r,k);
		if(r>mid)
			update(x<<1|1,l,r,k);
		pushup(x);
		return;
	}
	ll query(int x,int l,int r)
	{
		if(l<=tree[x].l&&r>=tree[x].r)
			return tree[x].sum%P;
		pushdown(x);
		int mid=tree[x].l+tree[x].r>>1;
		ll res=0;
		if(l<=mid)
			res=(res+query(x<<1,l,r))%P;
		if(r>mid)
			res=(res+query(x<<1|1,l,r))%P;
		return res%P;		
	}
}tree;
void dfs1(int x,int Fa)
{
	fa[x]=Fa;
	siz[x]=1;
	d[x]=d[Fa]+1;
	for(auto it:e[x])
	{
		if(it!=Fa)
		{
			dfs1(it,x);
			siz[x]+=siz[it];
			if(siz[it]>siz[son[x]])
				son[x]=it;
		}
	}
	return;
}
void dfs2(int x,int tp)
{
	top[x]=tp;
	dfn[x]=++thistime;
	rk[thistime]=x;
	if(!son[x])
		return;
	dfs2(son[x],tp);
	for(auto it:e[x])
	{
		if(it!=son[x]&&it!=fa[x])
			dfs2(it,it);
	}
	return;
}
ll query_edge(int x,int y)
{
	int fx=top[x],fy=top[y];
	ll res=0;
	while(fx!=fy)
	{
		if(d[fx]>=d[fy])
		{
			res=(res+tree.query(1,dfn[fx],dfn[x]))%P;
			x=fa[fx];
			fx=top[x];
		}
		else
		{
			res=(res+tree.query(1,dfn[fy],dfn[y]))%P;
			y=fa[fy];
			fy=top[y];
		}
	}
	if(dfn[x]<=dfn[y])
		res=(res+tree.query(1,dfn[x],dfn[y]))%P;
	else
		res=(res+tree.query(1,dfn[y],dfn[x]))%P;
	return res%P;
}
void update_edge(int x,int y,int c)
{
	int fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(d[fx]>=d[fy])
		{
			tree.update(1,dfn[fx],dfn[x],c);
			x=fa[fx];
			fx=top[x];
		}
		else
		{
			tree.update(1,dfn[fy],dfn[y],c);
			y=fa[fy];
			fy=top[y];
		}
	}
	if(dfn[x]<=dfn[y])
		tree.update(1,dfn[x],dfn[y],c);
	else
		tree.update(1,dfn[y],dfn[x],c);
	return;
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&root,&P);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1,u,v;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	d[root]=1;
	dfs1(root,0);
	dfs2(root,root);
	tree.build(1,1,n);
	while(m--)
	{
		int op,x,y,z;
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d%d%d",&x,&y,&z);
			update_edge(x,y,z);
		}
		if(op==2)
		{
			scanf("%d%d",&x,&y);
			printf("%lld\n",query_edge(x,y));
		}
		if(op==3)
		{
			scanf("%d%d",&x,&z);
			tree.update(1,dfn[x],dfn[x]+siz[x]-1,z);
		}
		if(op==4)
		{
			scanf("%d",&x);
			printf("%lld\n",tree.query(1,dfn[x],dfn[x]+siz[x]-1));
		}
	}
	return 0;
}
2023/8/13 10:31
加载中...