30分求助
查看原帖
30分求助
310790
RYANGSJ楼主2022/7/16 20:23

RT,其他点全WA

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[8000005],sum[8000005],add[8000005],mu[8000005],mod;
//mod是模数  sum是线段树数组  add是加法标记  mu 是乘法标记 
void build(int l,int r,int k){//建树 
	mu[k]=1,add[k]=0;
	if(l==r){
		sum[k]=a[l]%mod;
		return;
	}
	int mid=(l+r)/2;
	build(l,mid,k*2);
	build(mid+1,r,k*2+1);
	sum[k]=(sum[k*2]%mod+sum[k*2+1]%mod)%mod;
}
void Add1(int k,int l,int r,int v){//加 
	add[k]=(add[k]%mod+v%mod)%mod;
	sum[k]=(sum[k]%mod+((r-l+1)*v)%mod)%mod;
}
void Add2(int k,int l,int r,int v){//乘 
	add[k]=((add[k]%mod)*(v%mod))%mod;
	mu[k]=((mu[k]%mod)*(v%mod))%mod;
	sum[k]=((sum[k]%mod)*(v%mod))%mod;
}
void down(int k,int l,int r){
	int mid=(l+r)/2;
	sum[k*2]=((sum[k*2]%mod)*(mu[k]%mod))%mod;
	sum[k*2]=(sum[k*2]%mod+((mid-l+1)*add[k])%mod)%mod;
	//左边更新 
	sum[k*2+1]=((sum[k*2+1]%mod)*(mu[k]%mod))%mod;
	sum[k*2+1]=(sum[k*2+1]%mod+((r-(mid+1)+1)*add[k])%mod)%mod;
	//右边更新 
	mu[k*2]=((mu[k*2]%mod)*(mu[k]%mod))%mod;
	mu[k*2+1]=((mu[k*2+1]%mod)*(mu[k]%mod))%mod;
	//乘法标记下传 
	add[k*2]=(add[k*2]%mod+add[k]%mod)%mod;
	add[k*2+1]=(add[k*2+1]%mod+add[k]%mod)%mod;
	//加法标记下传 
	add[k]=0;
	mu[k]=1;
}
void updata1(int k,int l,int r,int x,int y,int v){//区间加 
	if(r<x||l>y)return;
	if(l>=x&&r<=y){
		Add1(k,l,r,v);
		return;
	}
	int mid=(l+r)/2;
	down(k,l,r);
	updata1(k*2,l,mid,x,y,v);
	updata1(k*2+1,mid+1,r,x,y,v);
	sum[k]=(sum[k*2]%mod+sum[k*2+1]%mod)%mod;
	return;
}
void updata2(int k,int l,int r,int x,int y,int v){//区间乘 
	if(r<x||l>y)return;
	if(l>=x&&r<=y){
		Add2(k,l,r,v);
		return;
	}
	int mid=(l+r)/2;
	down(k,l,r);
	updata2(k*2,l,mid,x,y,v);
	updata2(k*2+1,mid+1,r,x,y,v);
	sum[k]=(sum[k*2]%mod+sum[k*2+1]%mod)%mod;
	return;
}
int q(int k,int l,int r,int x,int y){
	if(r<x||l>y)return 0;
	if(l>=x&&r<=y){
		return sum[k]%mod;
	}
	down(k,l,r);
	int mid=(l+r)/2,ans=0;
	ans+=q(k*2,l,mid,x,y)%mod;
	ans%=mod;
	ans+=q(k*2+1,mid+1,r,x,y)%mod;
	return ans%mod;
}

signed main(){
	cin>>n>>m>>mod;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(1,n,1);
	for(int i=1;i<=m;i++){
		int c,x,y,k;
		cin>>c;
		if(c==1){
			cin>>x>>y>>k;
			updata2(1,1,n,x,y,k);//区间乘 
		}else if(c==2){
			cin>>x>>y>>k;
			updata1(1,1,n,x,y,k);//区间加 
		}else if(c==3){
			cin>>x>>y;
			cout<<(q(1,1,n,x,y)%mod)<<endl;//查询 
		}
	}
	return 0;
}
2022/7/16 20:23
加载中...