我觉得我的update1有问题,但不太明白怎么改QAQ
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=100005;
int MOD;
int n,m;
int d[4*N],b[4*N],a[N];
int pow(int a,int k)
{
if(k==1) return a%MOD;
if(k%2==1) return a*pow(a,k-1)%MOD;
else return pow(a,k/2)*pow(a,k/2)%MOD;
}
void build(int l,int r,int p)
{
if(l==r){
d[p]=a[l];
return ;
}
int mid=(l+r)/2;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
}
void update1(int l,int r,int ql,int qr,int k,int p)//乘
{
if(ql<=l&&qr>=r) {
d[p]=(d[p]*pow(k,r-l+1))%MOD;
b[p]+=k;
return ;
}
int mid=(l+r)/2;
if(b[p]&&l!=r)
{
d[p*2]=d[p*2]*(pow(b[p],mid-l+1)%MOD)%MOD,d[p*2+1]=d[p*2+1]*(pow(b[p],r-mid)%MOD)%MOD;
b[p*2]+=b[p],b[p*2+1]+=b[p];
b[p]=0;
}
if(ql<=mid) update1(l,mid,ql,qr,k,p*2);
if(qr>mid) update1(mid+1,r,ql,qr,k,p*2+1);
d[p]=(d[p*2]+d[p*2+1])%MOD;////////
}
void update2(int l,int r,int ql,int qr,int k,int p)
{
if(ql<=l&&qr>=r) {
d[p]=(d[p]+(r-l+1)*k%MOD)%MOD;
b[p]=(b[p]+k)%MOD;
return ;
}
int mid=(l+r)/2;
if(b[p]&&l!=r)
{
d[p*2]=(d[p*2]+b[p]*(mid-l+1)%MOD)%MOD,d[p*2+1]=(d[p*2+1]+b[p]*(r-mid))%MOD;
b[p*2]+=b[p],b[p*2+1]+=b[p];
b[p]=0;
}
if(ql<=mid) update2(l,mid,ql,qr,k,p*2);
if(qr>mid) update2(mid+1,r,ql,qr,k,p*2+1);
d[p]=d[p*2]+d[p*2+1];
}
int query(int l,int r,int ql,int qr,int p)
{
if(ql<=l&&qr>=r) return d[p]%MOD;
int mid=(l+r)/2;
if(b[p]&&l!=r)
{
d[p*2]=(d[p*2]+b[p]*(mid-l+1)%MOD)%MOD,d[p*2+1]=(d[p*2+1]+b[p]*(r-mid)%MOD)%MOD;
b[p*2]=(b[p*2]+b[p])%MOD,b[p*2+1]=(b[p*2+1]+b[p])%MOD;
b[p]=0;
}
int sum=0;
if(ql<=mid) sum=(sum+query(l,mid,ql,qr,p*2)%MOD)%MOD;
if(qr>mid) sum=(sum+query(mid+1,r,ql,qr,p*2+1)%MOD)%MOD;
return sum%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 op;
cin>>op;
if(op==1) {
int x,y,k;
cin>>x>>y>>k;
update1(1,n,x,y,k,1);//乘
}
else if(op==2){
int x,y,k;
cin>>x>>y>>k;
update2(1,n,x,y,k,1);//加
}
else {
int x,y;
cin>>x>>y;
cout<<query(1,n,x,y,1)%MOD<<endl;
}
}
return 0;
}