0pts求调
查看原帖
0pts求调
1111742
mincrafter_or_cy楼主2024/11/3 11:02
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 100005
int n,mod,q;
int a[N],sum[N<<2],add[N<<2],mul[N<<2];
void build(int l,int r,int p){
	mul[p]=1ll;
  	if(l==r){
	  	sum[p]=a[l]%mod;
		return;
	}
  	int m=l+((r-l)>>1);
  	build(l,m,p<<1);
  	build(m+1,r,(p<<1)|1l);
  	sum[p]=(sum[p<<1]+sum[(p<<1)|1l])%mod;
}
void pd(int p,int l,int r){
	if(add[p]==0&&mul[p]==1) return;
	int m=l+((r-l)>>1);
	sum[p<<1]=sum[p<<1]*mul[p]%mod;
	sum[(p<<1)|1]=sum[(p<<1)|1]*mul[p]%mod;
	sum[p<<1]=(sum[p<<1]+add[p]*(m-l+1l)%mod)%mod;
	sum[(p<<1)|1]=(sum[(p<<1)|1]+add[p]*(r-m)%mod)%mod;
	mul[p<<1]=(mul[p<<1]*mul[p])%mod;
	mul[(p<<1)|1]=(mul[(p<<1)|1l]*mul[p])%mod;
	add[p<<1]=(add[p<<1]*mul[p])%mod;
	add[(p<<1)|1]=(add[(p<<1)|1l]*mul[p])%mod;
    add[p<<1]=(add[p<<1]+add[p])%mod;
	add[(p<<1)|1l]=(add[(p<<1)|1l]+add[p])%mod;
	add[p]=0ll;mul[p]=1ll;
}
void upadd(int l,int r,int c,int s,int t,int p){
  	if(l<=s&&t<=r){
	  	sum[p]=(sum[p]+((t-s+1l)%mod)*c%mod)%mod;
		add[p]=(add[p]+c)%mod;
		return;
	} 
  	int m=s+((t-s)>>1);
	pd(p,s,t);
  	if(l<=m) upadd(l,r,c,s,m,p<<1);
  	if(r>m) upadd(l,r,c,m+1,t,(p<<1)|1l);
  	sum[p]=(sum[p<<1]+sum[(p<<1)|1l])%mod;
}
void upmul(int l,int r,int c,int s,int t,int p){
  	if(l<=s&&t<=r){
	  	sum[p]=sum[p]*(c%mod)%mod;
		add[p]=add[p]*(c%mod)%mod;
		mul[p]=mul[p]*(c%mod)%mod;
		return;
	}
  	int m=s+((t-s)>>1);
	pd(p,s,t);
  	if(l<=m) upmul(l,r,c,s,m,p<<1);
  	if(r>m) upmul(l,r,c,m+1,t,(p<<1)|1l);
  	sum[p]=(sum[p<<1]+sum[(p<<1)|1l])%mod;
}
int getsum(int l,int r,int s,int t,int p){
	if(l<=s&&t<=r) return sum[p]%mod;
	int m=s+((t-s)>>1);
	pd(p,s,t);
	int ans=0ll;
	if(l<=m) ans=getsum(l,r,s,m,p<<1)%mod;
	if(r>m) ans=(ans+getsum(l,r,m+1,t,(p<<1)|1l))%mod;
	return ans%mod;
}
signed main(){
	int type,x,y,k;
	scanf("%lld%lld%lld",&n,&q,&mod);
	for(int i=1;i<=n;i++) scanf("%lld",a+i);
	while(q--){
		scanf("%lld%lld%lld",&type,&x,&y);
		switch(type){
			case 1ll:
				scanf("%lld",&k);
				upmul(x,y,k,1ll,n,1ll);
				break;
			case 2ll:
				scanf("%lld",&k);
				upadd(x,y,k,1ll,n,1ll);
				break;
			case 3ll:printf("%lld\n",getsum(x,y,1ll,n,1ll)%mod);
		}
	}
	return 0;
}
2024/11/3 11:02
加载中...