树剖20pts求助(代码极烂但还是恳求看看)
查看原帖
树剖20pts求助(代码极烂但还是恳求看看)
315005
White_gugu楼主2021/7/8 21:35
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,r;
int a,b;
long long mod;
long long tree[800400]; 
long long val[800200];
long long tag[800200];
int head[800200];
int to[800200];
int next[800200];
int fa[800200];
int size[800200];
int dep[800200];
int son[800200];
int num[800200];
int dfn[800200];
int top[800200];
int tot=0,cnt=0,type;
int kx,ky;
long long kz;
long long ans=0;
inline long long read()
{
	char ch=getchar();
	long long num1=0;
	while(!(ch>='0'&&ch<='9'))
	ch=getchar();
	while(ch>='0'&&ch<='9')
	{
		num1=num1*10+ch-'0';
		ch=getchar();
	}
	return num1;
}
void xx(int u,int v)
{
	to[cnt]=v;
	next[cnt]=head[u];
	head[u]=cnt;
	cnt++;
}

void dfs1(int x,int father)
{
	dep[x]=dep[father]+1;
	size[x]=1;
	for(int i=head[x];i!=-1;i=next[i])
	{
		int y=to[i];
		if(y==father)
		continue;
		dfs1(y,x);
		fa[y]=x;
		size[x]+=size[y];
		if(size[y]>size[son[x]])
		son[x]=y;
	}
}
void dfs2(int x,int father)
{
	tot++;
	dfn[tot]=x;
	num[x]=tot;
	top[x]=father;
	if(son[x]!=0)
	dfs2(son[x],father);
	for(int i=head[x];i!=-1;i=next[i])
	{
		int y=to[i];
		if(y==fa[x]||y==son[x])
		continue;
		dfs2(y,y);
	}
}
void pushup(int k)
{
	tree[k*2]=(tree[k*2]+tag[k])%mod;
	tree[k*2+1]=(tree[k*2+1]+tag[k])%mod;
	tag[k*2]=(tag[k*2]+tag[k]);
	tag[k*2+1]=(tag[k*2+1]+tag[k]);
	tag[k]=0;
}
void build(int l,int r,int k)
{
	if(l==r)
	{
		tree[k]=val[dfn[l]]%mod;
		return;
	}
	int mid=(l+r)/2;
	build(l,mid,k*2);
	build(mid+1,r,k*2+1);
	tree[k]=(tree[k*2]+tree[k*2+1])%mod;
}
void change(int l,int r,int l1,int r1,int k,int x)
{   
   if(l<=l1&&r1<=r)
   {
   	  tree[k]+=x;
   	  tag[k]+=x;
   	  return;
   }       
   if(tag[k])
   pushup(k);
   int mid=(l1+r1)/2;
   if(l>mid) 
   change(l,r,mid+1,r1,k*2+1,x);
   else if(r<=mid) 
   change(l,r,l1,mid,k*2,x);
   else 
   {
   	change(l,mid,l1,mid,k*2,x);
   	change(mid+1,r,mid+1,r1,k*2+1,x);
   }
   tree[k]=(tree[k*2]+tree[k*2+1])%mod;
}
long long query(int L,int R,int l,int r,int k)
{	
	if(L<=l&&r<=R)
	return tree[k];
	int mid=(l+r)/2;    
	if(tag[k])
	pushup(k);
	if(L>mid)
	return query(L,R,mid+1,r,k*2+1);
	else if(R<=mid)
	return query(L,R,l,mid,k*2);
	else
	return (query(L,mid,l,mid,k*2)+query(mid+1,R,mid+1,r,k*2+1))%mod;
}
void lca(int x,int y,int z,int o)
{
	ans=0;
	int fx=top[x],fy=top[y];
	while(fx!=fy)
	{
		if(dep[top[x]]>=dep[top[y]])
		{
			if(o==0)
			change(num[x],num[top[x]],1,n,1,z);
			else
			ans=(ans+query(num[x],num[top[x]],1,n,1))%mod;
			x=fa[fx],fx=top[x];
		}
		else
		{
			if(o==0)
			change(num[y],num[top[y]],1,n,1,z);
			else
			ans=(ans+query(num[y],num[top[y]],1,n,1));
			y=fa[fy],fy=top[y];
		}
	}
//	printf("%d %d\n",num[10458],num[55578]);
	if(num[x]>num[y])
	if(o==0)
	change(num[y],num[x],1,n,1,z);
	else
	ans=(ans+query(num[y],num[x],1,n,1))%mod;
	else
	if(o==0)
	change(num[x],num[y],1,n,1,z);
	else
	ans=(ans+query(num[x],num[y],1,n,1))%mod;
	return;
}
int main()
{
	n=read(),m=read(),r=read(),mod=read();
	memset(head,-1,sizeof(head));
	for(int i=1;i<=n;i++)
	val[i]=read();
	for(int i=1;i<n;i++)
	{
		a=read(),b=read();
		xx(a,b),xx(b,a);
	}

	dfs1(r,0);
	dfs2(r,r);
	build(1,n,1);
//	printf("%d %d\n",num[10458],num[55578]);
	while(m--)
	{
		type=read();
		if(type==1)
		{
			kx=read(),ky=read(),kz=read();
			lca(kx,ky,kz,0);
		}
		else if(type==2)
		{
			ans=0;
			kx=read(),ky=read();
			lca(kx,ky,0,1);
			printf("%lld\n",ans%mod);
		}
		else if(type==3)
		{
			kx=read(),kz=read();
			change(num[kx],num[kx]+size[kx]-1,1,n,1,kz);
		}
		else if(type==4)
		{
			kx=read();
			printf("%lld\n",query(num[kx],num[kx]+size[kx]-1,1,n,1)%mod);
		}
	}
}

一个点WA,其他RE

经确认,系num数组不知为何被清为0(预处理没有问题)

恳求大佬们帮帮蒟蒻(找错找了1个多小时了QAQ)

2021/7/8 21:35
加载中...