社区讨论

萌新求助,样例输出0

P3384【模板】重链剖分 / 树链剖分参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo87047r
此快照首次捕获于
2023/10/27 13:48
2 年前
此快照最后确认于
2023/10/27 13:48
2 年前
查看原帖
照着题解第一篇写的,线段树部分不一样
CPP
#include<bits/stdc++.h>
#define pushup(now)  tree[now]=tree[now<<1]+tree[now<<1|1]
#define Max 200100
using namespace std;
int arr[Max],head[Max<<2],son[Max],id[Max],fa[Max],dep[Max],siz[Max],top[Max],vn[Max];
int cnt,num,mod,n,m,r,res;
struct node
{
	int l,r,len,sum,tag;
	node operator+(const node &x)const
	{
		return {l,x.r,len+x.len,sum+x.sum,0};
	}
}tree[Max<<2];
struct Edge
{
	int to,nxt,v;
}e[Max<<2];
inline void read(int &x)
{
	x=0;
	int f=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=(x<<1)+(x<<3)+(c^48);
		c=getchar();
	}
	x*=f;
}
inline void add(int from,int to)
{
	e[++cnt].nxt=head[from];
	e[cnt].to=to;
	//e[cnt].v=v;
	head[from]=cnt;
}
void build(int now,int x,int y)
{
	if(x==y)
	{
		tree[now]={x,x,1,vn[x],0};
		return;
	}
	int mid=(x+y)>>1;
	build(now<<1,x,mid);
	build(now<<1|1,mid+1,y);
	pushup(now);
}
inline void givetag(int now,int tag)
{
	if(tree[now].len==1)
	{
		tree[now].sum+=tag;
		return;
	}
	tree[now].sum+=tag*tree[now].len;
	tree[now].tag+=tag;
}
inline void pushdown(int now)
{
	givetag(now<<1,tree[now].tag);
	givetag(now<<1|1,tree[now].tag);
	tree[now].tag=0;
}
int query(int now,int x,int y)
{
	if(tree[now].tag) pushdown(now);
	if(x>tree[now].r||y<tree[now].l) return 0;
	else if(x<=tree[now].l&&y>=tree[now].r)
	{
		res+=tree[now].sum;
		res%=mod;
		return 0;
	}
	else return query(now<<1,x,y)+query(now<<1|1,x,y);
}
void modify(int now,int x,int y,int v)
{
	if(tree[now].tag)pushdown(now);
	if(x>tree[now].r||y<tree[now].l) return;
	else if(x<=tree[now].l&&y>=tree[now].r)
	{
		givetag(now,v);
		return;
	}
	else modify(now<<1,x,y,v),modify(now<<1|1,x,y,v);
	pushup(now);
}

inline void dfs1(int x,int f,int deep)
{
	dep[x]=deep;
	fa[x]=f;
	siz[x]=1;
	int maxsiz=-1;
	for(int i=head[x];i;i=e[i].nxt)
	{
		int t=e[i].to;
		if(t==f)
			continue;
		dfs1(t,x,deep+1);
		siz[x]+=siz[t];
		if(siz[t]>maxsiz)
		{
			son[x]=t;
			maxsiz=siz[t];
		}
	}
}
inline void dfs2(int x,int topf)
{
	id[x]=++cnt;
	vn[cnt]=arr[x];
	top[x]=topf;
	if(!son[x])
		return;
	dfs2(son[x],topf);
	for(int i=head[x];i;i=e[i].nxt)
	{
		int t=e[i].to;
		if(t==fa[x]||t==son[x])
			continue;
		dfs2(t,t);
	}
}
inline void qrange(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		res=0;
		query(1,x,y);
		ans+=res;
		ans%=mod;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	res=0;
	query(r,id[x],id[y]);
	ans+=res;
	printf("%d",ans%mod);
}
inline void uprange(int x,int y,int z)
{
	z%=mod;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
			swap(x,y);
		modify(1,id[x],id[x]+siz[x]-1,z);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	modify(r,id[x],id[y],z);
}
inline void qson(int x)
{
	res=0;
	query(r,id[x],id[x]+siz[x]-1);
	printf("%d",res%mod);
}
inline void upson(int x,int z)
{
	modify(r,id[x],id[x]+siz[x]-1,z);
}
int main()
{
	read(n),read(m),read(r),read(mod);
	for(int i=1;i<=n;++i)
		read(arr[i]);
	for(int i=1;i<n;++i)
	{
		int t1,t2;
		read(t1),read(t2);
		add(t1,t2),add(t2,t1);
	}
	dfs1(r,0,1),dfs2(r,r),build(r,1,n);
	for(int i=1;i<=m;++i)
	{
		int t,x,y,z;
		read(t);
		if(t==1)
		{
			read(x),read(y),read(z);
			uprange(x,y,z);
		}
		if(t==2)
		{
			read(x),read(y);
			qrange(x,y);
		}
		if(t==3)
		{
			read(x),read(z);
			upson(x,z);
		}
		if(t==4)
		{
			read(x);
			qson(x);
		}	
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...