萌新关于pushdown的一些疑惑
查看原帖
萌新关于pushdown的一些疑惑
584977
Susking楼主2022/5/8 10:59

如下,求助dalao,这两种写法有什么区别嘛,第一种3AC7WA,第二种全AC(除pushdown,其他地方完全一致)(第三个是全部的代码)

第一种:

void pushdown(long long u,long long l,long long mid,long long r){
	if(lazyc[u]!=1){
		tree[u<<1]=(tree[u<<1]*lazyc[u])%p;
		tree[u<<1|1]=(tree[u<<1|1]*lazyc[u])%p;
		
		lazyc[u<<1]=lazyc[u<<1]*lazyc[u]%p;
		lazyj[u<<1]=lazyj[u<<1]*lazyc[u]%p;
		
		lazyc[u<<1|1]=lazyc[u<<1|1]*lazyc[u]%p;
		lazyj[u<<1|1]=(lazyj[u<<1|1]*lazyc[u])%p;
		
		lazyc[u]=1;
	}
	if(lazyj[u]){
		tree[u<<1]=(tree[u<<1]+lazyj[u]*(mid-l+1))%p;
		tree[u<<1|1]=(tree[u<<1|1]+lazyj[u]*(r-mid))%p;
		
		lazyj[u<<1]=(lazyj[u<<1]+lazyj[u])%p;
		lazyj[u<<1|1]=(lazyj[u<<1|1]+lazyj[u])%p;
		
		lazyj[u]=0;
	}
}

第二种:

void pushdown(long long u,long long l,long long mid,long long r){
	tree[u<<1]=(tree[u<<1]*lazyc[u]+lazyj[u]*(mid-l+1))%p;
	tree[u<<1|1]=(tree[u<<1|1]*lazyc[u]+lazyj[u]*(r-mid))%p;
	
	lazyc[u<<1]=lazyc[u<<1]*lazyc[u]%p;
	lazyc[u<<1|1]=lazyc[u<<1|1]*lazyc[u]%p;
	lazyj[u<<1]=(lazyj[u<<1]*lazyc[u]+lazyj[u])%p;
	lazyj[u<<1|1]=(lazyj[u<<1|1]*lazyc[u]+lazyj[u])%p;
	lazyj[u]=0;lazyc[u]=1;
}

全部代码:

#include<bits/stdc++.h>
using namespace std;
long long n,m,p,lx,x,y,k,line[100020];
long long tree[400090],lazyc[400090],lazyj[400090];
void build(long long u,long long l,long long r){
	lazyc[u]=1;//非常重要!!因为我漏了。。。
	if(l==r){
		tree[u]=line[l]%p;
		return ;
	}
	long long gj=(l+r)>>1;
	build(u<<1,l,gj);
	build(u<<1|1,gj+1,r);
	tree[u]=(tree[u<<1]+tree[u<<1|1])%p;
}
void pushdown(long long u,long long l,long long mid,long long r){
	tree[u<<1]=(tree[u<<1]*lazyc[u]+lazyj[u]*(mid-l+1))%p;
	tree[u<<1|1]=(tree[u<<1|1]*lazyc[u]+lazyj[u]*(r-mid))%p;
	
	lazyc[u<<1]=lazyc[u<<1]*lazyc[u]%p;
	lazyc[u<<1|1]=lazyc[u<<1|1]*lazyc[u]%p;
	lazyj[u<<1]=(lazyj[u<<1]*lazyc[u]+lazyj[u])%p;
	lazyj[u<<1|1]=(lazyj[u<<1|1]*lazyc[u]+lazyj[u])%p;
	lazyj[u]=0;lazyc[u]=1;
}
void cheng(long long u,long long l,long long r){
	if(x<=l &&r<=y){
		lazyc[u]*=k;
		lazyj[u]=(lazyj[u]*k)%p;
		tree[u]=(tree[u]*k)%p;
		return ;
	}
	long long mid=(l+r)>>1;
	pushdown(u,l,mid,r);
	if(x<=mid) cheng(u<<1,l,mid);
	if(mid<y) cheng(u<<1|1,mid+1,r);
	tree[u]=(tree[u<<1]+tree[u<<1|1])%p;
}
void jia(long long u,long long l,long long r){
	if(x<=l &&r<=y){
		lazyj[u]=(lazyj[u]+k)%p;
		tree[u]=(tree[u]+k*(r-l+1))%p;
		return ;
	}
	long long mid=(l+r)>>1;
	pushdown(u,l,mid,r);
	if(x<=mid) jia(u<<1,l,mid);
	if(mid<y) jia(u<<1|1,mid+1,r);
	tree[u]=(tree[u<<1]+tree[u<<1|1])%p;
}
long long query(long long u,long long l,long long r){
	if(x<=l &&r<=y){
		return tree[u];
	}
	long long mid=(l+r)>>1,sum=0;
	pushdown(u,l,mid,r);
	if(x<=mid) sum=(sum+query(u<<1,l,mid))%p;
	if(mid<y) sum=(sum+query(u<<1|1,mid+1,r))%p;
	tree[u]=(tree[u<<1]+tree[u<<1|1])%p;
	return sum;
}

int main(){
	scanf("%lld%lld%lld",&n,&m,&p);
	for(long long i=1;i<=n;i++) scanf("%lld",&line[i]);
	build(1,1,n);
	while(m--){
		scanf("%lld%lld%lld",&lx,&x,&y);
		switch(lx){
			case 1:{
				scanf("%lld",&k);
				cheng(1,1,n);
				break;
			}
			case 2:{
				scanf("%lld",&k);
				jia(1,1,n);
				break;
			}
			case 3:{
				cout<<query(1,1,n)%p<<endl;
				break;
			}
		}
	}
}
2022/5/8 10:59
加载中...