改了半天,为啥输出是零啊
#include<iostream>
#include<cstdio>
#define N 1000001
#define ll long long
using namespace std;
ll n,m,p,a[N];
ll ans[N<<2],add[N<<2],mul[N<<2];
ll ls(ll x){return x<<1;}
ll rs(ll x){return x<<1|1;}
void scan(){cin>>n>>m>>p;for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);}
void push_up(ll p){
ans[p]=(ans[ls(p)]+ans[rs(p)]+p)%p;
}
void build(ll p,ll l, ll r){
add[p]=0,mul[p]=1;
if(l==r){
ans[p]=a[l];
return;
}
ll mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
push_up(p);
}
void f(ll p,ll l,ll r,ll k){//change操作
add[p]=(mul[k]*add[p]%p+add[k])%p;
mul[p]=(mul[p]*mul[k])%p;
ans[p]=(ans[p]*mul[k]%p+add[k]*(r-l+1)%p)%p;
}
void push_down(ll p,ll l,ll r){//下传标记
ll mid=(l+r)>>1;
f(ls(p),l,mid,p);
f(rs(p),mid+1,r,p);
add[p]=0,mul[p]=1;
return ;
}
//前两位查询区间,k是传递的tag值
void update_mul(ll nl,ll nr,ll l,ll r,ll p,ll k){
if(nl<=l&&r<=nr){
mul[p]=(mul[p]*k)%p;
add[p]=(add[p]*k)%p;
ans[p]=(ans[p]*k)%p;
return ;
}
push_down(p,l,r);
ll mid=(l+r)>>1;
if(nl<=mid) update_mul(nl,nr,l,mid,ls(p),k);
if(nr>mid) update_mul(nl,nr,mid+1,r,rs(p),k);
push_up(p);
}
void update_add(ll nl,ll nr,ll l,ll r,ll p,ll k){
if(nl<=l&&r<=nr){
ans[p]+=k*(r-l+1);
add[p]+=k;
return ;
}
push_down(p,l,r);
ll mid=(l+r)>>1;
if(nl<=mid) update_add(nl,nr,l,mid,ls(p),k);
if(nr>mid) update_add(nl,nr,mid+1,r,rs(p),k);
push_up(p);
}
ll query(ll qx,ll qy,ll l,ll r,ll p){
ll res=0;
if(qx<=l&&r<=qy)return ans[p];
ll mid=(l+r)>>1;
push_down(p,l,r);
if(qx<=mid) res+=query(qx,qy,l,mid,ls(p));
if(qy>mid) res+=query(qx,qy,mid+1,r,rs(p));
return (res+p)%p;
}
int main(){
ll al,b_1,c_1,d_1,b_2,c_2,d_2,e,f;
scan();
build(1,1,n);
for(int i=1;i<=N*4;i++) mul[i]=1;
while(m--){
scanf("%lld",&al);
switch(al){
case 1:{
scanf("%lld%lld%lld",&b_1,&c_1,&d_1);
update_add(b_1,c_1,1,n,1,d_1);
break;
}
case 2:{
scanf("%lld%lld%lld",&b_2,&c_2,&d_2);
update_add(b_2,c_2,1,n,1,d_2);
break;
}
case 3:{
scanf("%lld%lld",&e,&f);
printf("%lld\n",query(e,f,1,n,1));
break;
}
}
}
return 0;
}