想要练习一下动态开点,然而挂了……
#include<iostream>
#include<cstdio>
#define MAXN 100010
using namespace std;
struct node
{
int vis;
int mul;
int plus;
int lson,rson;
}
t[MAXN<<1];
int n,m,MOD,tot,root;
int a[MAXN];
void push_up(int p)
{
t[p].vis=t[t[p].lson].vis+t[t[p].rson].vis;
t[p].vis%=MOD;
}
void build(int &p,int l,int r)
{
if(!p)
p=++tot;
t[p].plus=0;
t[p].mul=1;
if(l==r)
{
t[p].vis=a[l]%MOD;
return;
}
int mid=(l+r)>>1;
build(t[p].lson,l,mid);
build(t[p].rson,mid+1,r);
push_up(p);
}
void push_tag(int &p,int l,int r,int m,int k)
{
if(!p)
{
p=++tot;
t[p].mul=1;
t[p].plus=0;
}
t[p].vis*=m;
t[p].vis%=MOD;
t[p].vis+=(r-l+1)*k%MOD;
t[p].vis%=MOD;
t[p].mul*=m;
t[p].mul%=MOD;
t[p].plus*=m;
t[p].plus%=MOD;
t[p].plus+=k;
t[p].plus%=MOD;
}
void push_down(int p,int l,int r)
{
int mid=(l+r)>>1;
push_tag(t[p].lson,l,mid,t[p].mul,t[p].plus);
push_tag(t[p].rson,mid+1,r,t[p].mul,t[p].plus);
t[p].plus=0;
t[p].mul=1;
}
void update_plus(int &p,int l,int r,int L,int R,int k)
{
if(!p)
{
p=++tot;
t[p].mul=1;
}
if(L<=l&&R>=r)
{
push_tag(p,l,r,1,k);
return;
}
int mid=(l+r)>>1;
push_down(p,l,r);
if(L<=mid);
update_plus(t[p].lson,l,mid,L,R,k);
if(R>=mid+1);
update_plus(t[p].rson,mid+1,r,L,R,k);
push_up(p);
}
void update_mul(int &p,int l,int r,int L,int R,int k)
{
if(!p)
{
p=++tot;
t[p].mul=1;
}
if(L<=l&&R>=r)
{
push_tag(p,l,r,k,0);
return;
}
int mid=(l+r)>>1;
push_down(p,l,r);
if(L<=mid)
update_mul(t[p].lson,l,mid,L,R,k);
if(R>=mid+1)
update_mul(t[p].rson,mid+1,r,L,R,k);
push_up(p);
}
int query(int p,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
return t[p].vis%MOD;
int mid=(l+r)>>1;
int res=0;
push_down(p,l,r);
if(L<=mid)
res+=query(t[p].lson,l,mid,L,R);
if(R>=mid+1)
res+=query(t[p].rson,mid+1,r,L,R);
return res%MOD;
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&MOD);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(root,1,n);
for(int i=1;i<=m;i++)
{
int op,x,y,k;
scanf("%lld",&op);
if(op==1)
{
scanf("%lld%lld%lld",&x,&y,&k);
update_mul(root,1,n,x,y,k);
}
else if(op==2)
{
scanf("%lld%lld%lld",&x,&y,&k);
update_plus(root,1,n,x,y,k);
}
else
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(root,1,n,x,y));
}
}
return 0;
}