求助!关于建树部分的疑问
查看原帖
求助!关于建树部分的疑问
716721
leo12334楼主2024/7/8 08:19

在调试的时候发现一个很神奇的问题,

void build(int p,int l,int r){
	t[p].l=l;t[p].r=r;
	t[p].len=r-l+1;t[p].flag=0;
	if(l==r){t[p].v=a[b[l]];return;}
	mid=(l+r)>>1;cout<<l<<' '<<r<<' '<<mid<<endl;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].v=(t[p*2].v+t[p*2+1].v)%mod;
}

这一段代码不正确,会出现1 3,1 2,2 3这种重复计算的情况,

void build(int p,int l,int r){
	t[p].l=l;t[p].r=r;
	int mid=(l+r)/2;t[p].flag=0;
	t[p].len=r-l+1;
//	cout<<l<<' '<<r<<' '<<mid<<endl;
	if(l==r){t[p].v=a[b[l]];return ;}
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].v=(t[p*2].v+t[p*2+1].v)%mod;
}

而这一段就是正确的。蒟蒻的我百思不得其解,求助各位大佬帮助


下面是ac的代码

#include<bits/stdc++.h>
using namespace std;
#define N 500860
#define ll long long
#define in read() 
ll a[N],b[N],mod;
int fa[N],n,m,dfn[N],cnt,x,y,z,v,l,r,mid,root,op,deep[N],head[N],tp[N],size[N],son[N],tt;
struct node{
	int next,to;
}e[N*2];
struct tree{
	int l,r,len;
	ll v,flag;
}t[N*4];
void down(int p){
	if(t[p].flag==0)return;
	ll v=t[p].flag;
	t[p*2].v+=v*t[p*2].len;    t[p*2].v%=mod;
	t[p*2+1].v+=v*t[p*2+1].len;t[p*2+1].v%=mod;
	t[p*2].flag+=v;  t[p*2+1].flag+=v;
	t[p*2].flag%=mod;t[p*2+1].flag%=mod;
	t[p].flag=0;
} 
void add(int x,int y){
	e[++cnt].next=head[x];
	e[cnt].to=y;
	head[x]=cnt;
}
ll read(){ 
	ll x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;c=getchar();
	} 
	while(c<='9'&&c>='0'){
		x=(x<<3)+(x<<1)+c-'0';
		c=getchar();
	}
	return x*f;
}
void dfs1(int x){
	size[x]=1;
	int big=0;
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].to;
		if(y==fa[x])continue;
		fa[y]=x;deep[y]=deep[x]+1;
		dfs1(y);
		size[x]+=size[y];
		if(size[y]>big)big=size[y],son[x]=y;
	}
}
void dfs2(int x,int tou){
	dfn[x]=++tt;
	b[tt]=x;
	tp[x]=tou;
	if(son[x]) dfs2(son[x],tou);
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].to;
		if(y!=fa[x]&&y!=son[x]){
			dfs2(y,y);
		}
	}
}
//void build(int p,int l,int r){
//	t[p].l=l;t[p].r=r;
//	t[p].len=r-l+1;t[p].flag=0;
//	if(l==r){t[p].v=a[b[l]];return;}
//	mid=(l+r)>>1;cout<<l<<' '<<r<<' '<<mid<<endl;

//	build(p*2,l,mid);
//	build(p*2+1,mid+1,r);
//	t[p].v=(t[p*2].v+t[p*2+1].v)%mod;
//}
void build(int p,int l,int r){
	t[p].l=l;t[p].r=r;
	int mid=(l+r)/2;t[p].flag=0;
	t[p].len=r-l+1;
//	cout<<l<<' '<<r<<' '<<mid<<endl;
	if(l==r){t[p].v=a[b[l]];return ;}
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].v=(t[p*2].v+t[p*2+1].v)%mod;
}
void add(int p,int l,int r,int v){
	if(l>t[p].r||r<t[p].l)return;
	else if(l<=t[p].l&&r>=t[p].r) {
		t[p].v+=t[p].len*v;t[p].v%=mod;
		t[p].flag+=v; t[p].flag%=mod;
	}
	else{
		down(p);
		add(p*2,l,r,v);add(p*2+1,l,r,v);
		t[p].v=(t[p*2].v+t[p*2+1].v)%mod;
	}
}
ll query(int p,int l,int r){
	if(l>t[p].r||r<t[p].l)return 0;
	else if(l<=t[p].l&&r>=t[p].r) return t[p].v;
	else{
		down(p);
		return query(p*2,l,r)+query(p*2+1,l,r);
	}
}
void op1(int x,int y,int z){
	while(tp[x]!=tp[y]){
		if(deep[tp[x]]>deep[tp[y]])swap(x,y);
		add(1,dfn[tp[y]],dfn[y],z);
		y=fa[tp[y]];
	}
	if(deep[x]>deep[y])swap(x,y);
	add(1,dfn[x],dfn[y],z);
}
void op2(int x,int y){
	ll ans=0;
	while(tp[x]!=tp[y]){
		if(deep[tp[x]]>deep[tp[y]])swap(x,y);
		ans+=query(1,dfn[tp[y]],dfn[y]);ans%=mod;
		y=fa[tp[y]];
	}
	if(deep[x]>deep[y])swap(x,y);
	ans+=query(1,dfn[x],dfn[y]);
	cout<<ans%mod<<endl;
}
void op3(int x,int z){
	add(1,dfn[x],dfn[x]+size[x]-1,z);
}
void op4(int x){
	cout<<query(1,dfn[x],dfn[x]+size[x]-1)%mod<<endl;
}
int main(){
	n=in,m=in,root=in,mod=in;
	for(int i=1;i<=n;i++) a[i]=in;
	for(int i=1;i<n;i++){
		x=in,y=in;
		add(x,y);add(y,x);
	}
	dfs1(root);
	dfs2(root,root);
	build(1,1,n);
	while(m--){
		op=in;
		if(op==1){ x=in,y=in,z=in;op1(x,y,z);}
		else if(op==2){	x=in,y=in;op2(x,y);}
		else if(op==3){ x=in,y=in;op3(x,y);}
		else{ x=in;op4(x);}
	}
	return 0; 
} 
2024/7/8 08:19
加载中...