求助,请路过的巨佬帮忙看看
查看原帖
求助,请路过的巨佬帮忙看看
51061
幻离ian楼主2021/3/16 18:19

调了一下午没调出来QAQ

#include <iostream>
#include <cstdio>
using namespace std;
int n,m,t,x,y,k;
int a[100005],sum[400005],p,add[400005],add2[400005];
void build(int k,int l ,int r){
	if(l==r){
		sum[k]=a[l]%p;
		return;
	}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	sum[k]=sum[k<<1]+sum[k<<1|1];
	sum[k]%=p;
}
void Add(int k,int l,int r,long long v){
	add[k]+=v;
	add[k]%=p;
	sum[k]+=v*(r-l+1);
	sum[k]%=p;
}
void Add2(int k,int l,int r,long long v){
	add2[k]*=v;
	add2[k]%=p;
	
	sum[k]*=v;
	sum[k]%=p;
	add[k]*=v;
	add[k]%=p;
}
void pushdown(int k,int l,int r,int mid){
	if(add2[k]>1){
		Add2(k<<1,l,mid,add2[k]);
		Add2(k<<1|1,mid+1,r,add2[k]);
		add2[k]=1;
	}
	if(add[k]){
		Add(k<<1,l,mid,add[k]);
		Add(k<<1|1,mid+1,r,add[k]);
		add[k]=0;
	}
}
void update(int k,int l,int r,int x,int y,long long v){
	if(l>=x&&r<=y)return Add(k,l,r,v);
	int mid=(l+r)>>1;
	pushdown(k,l,r,mid);
	if(x<=mid)update(k<<1,l,mid,x,y,v);
	if(mid+1<=y)update(k<<1|1,mid+1,r,x,y,v);
	sum[k]=sum[k<<1]+sum[k<<1|1];
	sum[k]%=p;
}
void update2(int k,int l,int r,int x,int y,long long v){//乘法
	if(l>=x&&r<=y)return Add2(k,l,r,v);
	int mid=(l+r)>>1;
	pushdown(k,l,r,mid);
	if(x<=mid)update2(k<<1,l,mid,x,y,v);
	if(mid+1<=y)update2(k<<1|1,mid+1,r,x,y,v);
	sum[k]=sum[k<<1]+sum[k<<1|1];
	sum[k]%=p;
}
long long query(int k,int l,int r,int x,int y){
	if(l>=x&&r<=y)return sum[k]%p;
	int mid=(l+r)>>1;
	long long res=0;
	pushdown(k,l,r,mid);
	if(mid>=x)res+=query(k<<1,l,mid,x,y);
	res%=p;
	if(mid+1<=y)res+=query(k<<1|1,mid+1,r,x,y);
	return res%p;
}	

int main(){
	cin>>n>>m>>p;
	for(int i = 0;i<400005;i++)
		add2[i]=1;
	for(int i = 1;i<=n;i++)
		scanf("%lld",&a[i]);
	build(1,1,n);
	for(int i= 1;i<=m;i++){
		scanf("%d",&t);
		if(t==1){
			scanf("%d%d%d",&x,&y,&k);
			update2(1,1,n,x,y,k);
		}else if(t==2){
			scanf("%d%d%d",&x,&y,&k);
			update(1,1,n,x,y,k);
		}else{
			scanf("%d%d",&x,&y);
			printf("%lld\n",query(1,1,n,x,y));
		}
	}
	return 0;
}
2021/3/16 18:19
加载中...