求助树剖,除了#1#4全WA
查看原帖
求助树剖,除了#1#4全WA
653286
zhfaz123楼主2023/3/30 13:40

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<stack>
#include<iostream>
#include<vector>
#define N (int(1e5))
using namespace std;
int son[N+1],id[N+1],sz[N+1],fa[N+1],dep[N+1],dfc,top[N+1],w[N+1],nw[N+1];//树的变量
int n,m,p,q;
vector<int> edge[N+1];//图
struct g
{
	int l,r;
	long long lazy,data;
	g():l(0),r(0),lazy(0),data(0){};
}a[((N)<<2)+1];//线段树
//线段树
void build(int root,int l,int r)
{
	a[root].l=l;
	a[root].r=r;
	int mid=l+r>>1;
	if(l==r)
	{
		a[root].data=nw[l]%p;
		return ;
	}
	build(root<<1,l,mid);
	build(root<<1|1,mid+1,r);
    a[root].data=a[root<<1].data+a[root<<1|1].data;
}
inline void push_down(int root)
{
	if(a[root].lazy)
	{
		int mid=a[root].l+a[root].r>>1;
		a[root<<1].lazy+=a[root].lazy;
		a[root<<1|1].lazy+=a[root].lazy;
		a[root<<1].data+=(a[root<<1].r-a[root<<1].l+1)*a[root].lazy;
		a[root<<1|1].data+=(a[root<<1|1].r-a[root<<1|1].l+1)*a[root].lazy;
		a[root].lazy=0;
	}
}
void add(int root,int l,int r,long long k)
{
	int mid=a[root].l+a[root].r>>1;
	if(l <= a[root].l && r >=a[root].r)
	{
		a[root].data=(a[root].data%p+k%p)%p;
		a[root].lazy=(a[root].lazy%p+k%p)%p;
		return;
	}
	push_down(root);
	if(l<=mid)add(root<<1,l,r,k);
	if(r>mid)add(root<<1|1,l,r,k);
	a[root].data=a[root<<1].data+a[root<<1|1].data;
	return ;
}
int query(int root,int l,int r)
{
	int mid=a[root].l+a[root].r>>1;
	long long ret=0;
	if(l <= a[root].l && r >=a[root].r)
	{
		return a[root].data%p;
	}
	push_down(root);
	if(l<=mid)ret=(ret%p+query(root<<1,l,r)%p)%p;
	if(r>mid)ret=(ret%p+query(root<<1|1,l,r)%p)%p;
	a[root].data=a[root<<1].data+a[root<<1|1].data;
	return ret;
}
//线段树结束
void dfs(int root,int f,int deep)
{
	fa[root]=f;
	sz[root]=1;
	dep[root]=deep;
	int hvs=-1;
	for(auto &i:edge[root])
	{
		if(i==f)
			continue;
		dfs(i,root,deep+1);
		sz[root]+=sz[i];
		if(sz[i]>hvs)
		{
			hvs=sz[i];
			son[root]=i;
		}
	}
}//第一遍dfs
void dfs2(int root,int topf)
{

	id[root]=++dfc;
	nw[id[root]]=w[root];
	top[root]=topf;
	if(!son[root]) 
		return;
	dfs2(son[root],topf);
	for(auto &i:edge[root])
	{
		if(i == son[root] || i == fa[root])
			continue;
		dfs2(i,i);
	}
}//第二遍dfs
void addpath(int x,int y,long long k)
{
	while(top[x] != top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		add(1,id[top[x]],id[x],k%p);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y])
		swap(x,y);
	add(1,id[y],id[x],k%p);
	return ;
}//增加路径和
long long querypath(int x,int y)
{
	long long ret=0;
	while(top[x] != top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		ret=(ret%p+query(1,id[top[x]],id[x])%p)%p;
		x=fa[top[x]];
	}
	if(dep[x]<dep[y])
	{
		swap(x,y);
	}
	ret=(ret%p+query(1,id[y],id[x])%p)%p;
	return ret;
}//查询路径和
void addtree(int x,long long k)
{
	add(1,id[x],id[x]+sz[x]-1,k);
}//增加子树和
long long querytree(int x)
{
	long long ret=0;
	ret=(ret%p+query(1,id[x],id[x]+sz[x]-1)%p)%p;
	return ret;
}//查询子树和
int main()
{
	scanf("%d %d %d %d",&n,&q,&m,&p);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&w[i]);
	}
	for(int i=1;i<=n-1;i++)
	{
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(m,0,1);
	dfs2(m,m);
	build(1,1,n);//建树
	for(int i=1;i<=q;i++)
	{
		int op;
		scanf("%d",&op);
		switch (op) 
		{
			case 1:
			{
				int x,y;
				long long k;
				scanf("%d %d %lld",&x,&y,&k);
				addpath(x,y,k);
				break;
			}
			case 2:
			{
				int x,y;
				scanf("%d %d",&x,&y);
				printf("%lld\n",querypath(x,y)%p);
				break;
			}
			case 3:
			{
				int x;
				long long k;
				scanf("%d %lld",&x,&k);
				addtree(x,k);
                break;
			}
			case 4:
			{
				int x;
				scanf("%d",&x);
				printf("%lld\n",querytree(x)%p);
                break;			
			}
			default:
				break;
		}
	}
	return 0;
}
2023/3/30 13:40
加载中...