Help!
查看原帖
Help!
68960
M_and_P_楼主2021/2/2 17:10

求帮助QAQ~~

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005<<2
#define M 200005
#define ll long long
using namespace std;
int n,m,root,op,rk[N];
ll P,_sum,k,a[N];
int lx,ly,cnt,tot;
struct Tree
{
	int L[N],R[N];
	ll add[N],sum[N];
	void build(int o,int l,int r)
	{
		int lc=o*2,rc=o*2+1,mid=l+(r-l)/2;
		L[o]=l;R[o]=r;
		if(l==r){sum[o]=a[rk[l]];return ;}
		build(lc,l,mid);
		build(rc,mid+1,r);
		sum[o]=(sum[lc]+sum[rc])%P;
	}
	void spread(int o)
	{
		int lc=o*2,rc=o*2+1;
		sum[lc]+=add[o]*(ll)(R[lc]-L[lc]+1);
		sum[rc]+=add[o]*(ll)(R[rc]-L[rc]+1);
		add[lc]+=add[o];
		add[rc]+=add[o];
		add[o]=0LL;
		sum[lc]%=P;
		sum[rc]%=P;
		add[lc]%=P;
		add[rc]%=P;
	}
	void update(int o)
	{
		int l=L[o],r=R[o];
		int mid=l+(r-l)/2;
		if (lx<=l&&r<=ly)
		{
			add[o]+=k;
			add[o]%=P;
			sum[o]+=k*(ll)(r-l+1);
		}
		else
		{
			spread(o);
			if (lx<=mid)update(o*2);
			if (ly>mid)update(o*2+1);
			sum[o]=sum[l]+sum[r];
			sum[o]%=P;
		}
		
	}
	void ask(int o)
	{
		int lc=o*2,rc=o*2+1,l=L[o],r=R[o];
		int mid=l+(r-l)/2;
		if (lx<=l&&r<=ly)
		{
			_sum+=sum[o];
			_sum%=P;
		}
		else
		{
			spread(o);
			if (lx<=mid)ask(lc);
			if (ly>mid)ask(rc);
		}
	}
}tree;
struct edges{
	int to;
	int nxt;
}edge[M];
int head[M];
void add(int x,int y)
{
	edge[++tot].nxt=head[x];
	edge[tot].to=y;
	head[x]=tot;
}
int size[N],fa[N],son[N],deep[N];
bool vis[N];
void dfs1(int u,int f,int d)
{
	vis[u]=true;
	fa[u]=f;
	deep[u]=d+1;
	size[u]=1;
	for (int i=head[u];i;i=edge[i].nxt)
	{		
		int v=edge[i].to;
		if (vis[v])continue;

		dfs1(v,u,d+1);
		size[u]+=size[v];
		if (size[v]>size[son[u]])
		son[u]=v;
	}
}
int top[N],id[N],last[N];
void dfs2(int u,int t)
{
	vis[u]=true;
	top[u]=t;
	id[u]=++cnt;
	rk[cnt]=u;
	last[u]=id[u]+size[u]-1;
	if (son[u])dfs2(son[u],t);
	for (int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if (vis[v])continue;
		dfs2(v,v);
	}
}
inline void control()
{
	if (op==1)
	{
		tree.update(1);
	}
	if (op==2)
	{
		tree.ask(1);
	}
}
void lca(int x,int y)
{
	while(top[x]!=top[y])
	{
		if (deep[top[x]]<deep[top[y]])swap(x,y);
		lx=id[top[x]];
		ly=id[x];
		control();
		x=fa[top[x]];
	}
	lx=id[x],ly=id[y];
	if (deep[x]>deep[y])swap(lx,ly);
	control();
}
int main()
{
	scanf("%d%d%d%lld",&n,&m,&root,&P);
	for (int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
	}
	for (int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	memset(vis,0,sizeof(vis));
	dfs1(root,0,0);
	memset(vis,0,sizeof(vis));
	dfs2(root,root);
	tree.build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d",&op);
		if (op==1)
		{
			scanf("%d%d%lld",&x,&y,&k);
			lca(x,y);
		}
		if (op==2)
		{
			scanf("%d%d",&x,&y);
			_sum=0LL;
			lca(x,y);
			printf("%lld\n",_sum);	
		}
		if (op==3)
		{
			scanf("%d%lld",&x,&k);
			lx=id[x];
			ly=last[x];
			tree.update(1);
		}
		if (op==4)
		{
			scanf("%d",&x);
			lx=id[x];
			ly=last[x];
			_sum=0LL;
			tree.ask(1);
			printf("%lld\n",_sum);
		}
	}
}
2021/2/2 17:10
加载中...