看了一圈讨论区30分的,感觉错的不一样
#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define maxn 100001
#define ll long long
#define ull unsigned long long
#define ls k<<1
#define rs k<<1|1
using namespace std;
int n,m,p;
int a[maxn];
int op,x,y,d;
struct node
{
int l,r;
ll s,lz1,lz2;
}t[maxn<<2];
void build(int l,int r,int k)
{
t[k].l=l;
t[k].r=r;
t[k].lz2=1;
if(l==r)
{
t[k].s=a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
t[k].s=t[ls].s+t[rs].s;
}
void pushdown(int k)
{
t[ls].s=(t[ls].s*t[k].lz2+t[k].lz1*(t[ls].r-t[ls].l+1))%p;
t[rs].s=(t[rs].s*t[k].lz2+t[k].lz1*(t[rs].r-t[rs].l+1))%p;
t[ls].lz2=(t[ls].lz2*t[k].lz2)%p;
t[rs].lz2=(t[rs].lz2*t[k].lz2)%p;
t[ls].lz1=(t[ls].lz1+t[k].lz1)%p;
t[rs].lz1=(t[rs].lz1+t[k].lz1)%p;
t[k].lz1=0;
t[k].lz2=1;
return;
}
void pro(int x,int y,int k,int d)
{
if(t[k].l>=x&&t[k].r<=y)
{
t[k].s=(t[k].s*d)%p;
t[k].lz2=(t[k].lz2*d)%p;
t[k].lz1=(t[k].lz1*d)%p;
return;
}
pushdown(k);
int mid=(t[k].l+t[k].r)>>1;
if(mid>=x)
{
pro(x,y,ls,d);
}
if(mid<y)
{
pro(x,y,rs,d);
}
t[k].s=(t[ls].s+t[rs].s)%p;
}
void sum(int x,int y,int k,int d)
{
if(t[k].l>=x&&t[k].r<=y)
{
t[k].s=(t[k].s+d*(t[k].r-t[k].l+1))%p;
t[k].lz1=(t[k].lz1+d)%p;
return;
}
pushdown(k);
int mid=(t[k].l+t[k].r)>>1;
if(mid>=x)
{
sum(x,y,ls,d);
}
if(mid<y)
{
sum(x,y,rs,d);
}
t[k].s=(t[ls].s+t[rs].s)%p;
}
ll ask(int x,int y,int k)
{
if(t[k].l>=x&&t[k].r<=y)
{
return t[k].s;
}
pushdown(k);
int mid=(t[k].l+t[k].r)>>1;
ll ans=0;
if(mid>=x)
{
ans=(ans+ask(x,y,ls));
}
if(mid<y)
{
ans=(ans+ask(x,y,rs));
}
return ans%p;
}
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
cin>>n>>m>>p;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,n,1);
for(int i=1;i<=m;i++)
{
cin>>op>>x>>y;
if(op==1)
{
cin>>d;
pro(x,y,1,d);
}
else if(op==2)
{
cin>>d;
sum(x,y,1,d);
}
else if(op==3)
{
cout<<ask(x,y,1)%p<<endl;
}
}
fclose(stdin);
fclose(stdout);
return 0;
}