求大神看看,第一次打树剖,P3384
  • 板块学术版
  • 楼主Name1
  • 当前回复5
  • 已保存回复5
  • 发布时间2022/6/3 16:32
  • 上次更新2023/10/28 00:01:45
查看原帖
求大神看看,第一次打树剖,P3384
648660
Name1楼主2022/6/3 16:32
#include<iostream>
#include<cstdio>
#define time time1
using namespace std;
const int N=1e5+10;
int cnt,time1,head[N],w[N],dep[N],size[N],fa[N],son[N],dfn[N],rnk[N],top[N];
struct Edge{int next,to;}g[N<<1];
void add(int u,int v)
{
	g[++cnt]=(Edge){head[u],v};
	head[u]=cnt;
}
int n,m,MOD,root;
//线段树部分
#define ls x<<1
#define rs x<<1|1
int ty[N<<2],d[N<<2];
inline void build(int x,int l,int r)
{
	if(l==r)
	{
		ty[x]=rnk[l]%MOD;
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	ty[x]=(ty[ls]+ty[rs])%MOD;
}//建树 
inline void pushdown(int x,int l,int r,int mid)
{
	if(!d[x]) return;
	d[ls]+=d[x],d[rs]+=d[x];
	ty[ls]+=(mid-l+1)*d[x];
	ty[rs]+=(r-mid)*d[x];
	d[x]=0;
}//下传懒标记
inline int query(int x,int l,int r,int ql,int qr)
{
	if(ql>r||qr<l) return 0;
	if(ql<=l&&r<=qr) return ty[x];
	int mid=(l+r)>>1;
	pushdown(x,l,r,mid);
	return query(ls,l,mid,ql,qr)+query(rs,mid+1,r,ql,qr);
}
inline void update(int x,int l,int r,int ql,int qr,int y)
{
	if(ql>r||qr<l) return;
	if(ql<=l&&r<=qr) 
	{
		ty[x]=(ty[x]+(r-l+1)*y)%MOD,d[x]=y;
		return;
	}
	int mid=(l+r)>>1;
	pushdown(x,l,r,mid);
	update(ls,l,mid,ql,qr,y);
	update(rs,mid+1,r,ql,qr,y);
	ty[x]=(ty[ls]+ty[rs])%MOD;
}
//
int first_query(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=(ans+query(1,1,n,dfn[top[x]],dfn[x]))%MOD;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans+=query(1,1,n,dfn[x],dfn[y])%MOD;
	return ans;
}
int second_query(int x)
{
	return query(1,1,n,dfn[x],dfn[x]+size[x]-1);
}
void first_update(int x,int y,int k)
{
	k%=MOD;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,1,n,dfn[top[x]],dfn[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	update(1,1,n,dfn[x],dfn[y],k);
}
void second_update(int x,int k)
{
	update(1,1,n,dfn[x],dfn[x]+size[x]-1,k);
}
inline int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
	return x*f;
}
inline void dfs1(int x,int f,int deep)
{
	dep[x]=deep,fa[x]=f,size[x]=1;
	int maxson=-1;
	for(int i=head[x];i;i=g[i].next)
	{
		int v=g[i].to;if(v==f) continue;
		dfs1(v,x,deep+1);
		size[x]+=size[v];
		if(maxson<size[v])maxson=size[v],son[x]=v;
	}
}
inline void dfs2(int x,int topp)
{
	top[x]=topp;dfn[x]=++time;rnk[time]=w[x];
	if(!son[x]) return;
	dfs2(son[x],topp);
	for(int i=head[x];i;i=g[i].next)
	if(g[i].to!=son[x]&&g[i].to!=fa[x])dfs2(g[i].to,g[i].to);
}
int main()
{
	n=read(),m=read(),root=read(),MOD=read();
	for(int i=1;i<=n;i++) w[i]=read();
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read();
		add(u,v),add(v,u);
	}
	dfs1(root,0,1);
	dfs2(root,root);
	while(m--)
	{
		int op=read();
		if(op==1) 
		{
			int x=read(),y=read(),z=read();
			first_update(x,y,z);
		}
		else if(op==2)
		{
			int x=read(),z=read();
			second_update(x,z);
		}
		else if(op==3)
		{
			int x=read(),y=read();
			printf("%d\n",first_query(x,y));
		}
		else 
		{
			int x=read();
			printf("%d\n",second_query(x));
		}
	}
	return 0;
}
2022/6/3 16:32
加载中...