传送门:https://www.luogu.org/problem/P3373
标记下传,这种东西就是在求和和更改的时候进行pushdown把标记(各种标记,类似于寒冰标记、痛苦标记、穹妹标记……)下传,来节省时间。
还是挺简单的,主要问题处在pushdown上但多看看就会了
#include<bits/stdc++.h>
using namespace std;
long long n,m,p;
long long multag[1000009];
long long addtag[1000009];
long long seg[4000009];
long long num[1000009];
inline long long kd()
{
long long x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
return x*f;
}
inline long long ls(long long x){return x<<1;}
inline long long rs(long long x){return x<<1|1;}
void build(long long now,long long l,long long r)
{
addtag[now]=0;
multag[now]=1;
if(l==r)
{
seg[now]=num[l]%p;
return;
}
long long mid=(l+r)>>1;
build(ls(now),l,mid);
build(rs(now),mid+1,r);
seg[now]=(seg[ls(now)]+seg[rs(now)])%p;
return;
}
void pushdown(long long now,long long l,long long r)
{
long long mid=(l+r)>>1;
seg[ls(now)]=(seg[ls(now)]*multag[now]+addtag[now]*(mid-l+1))%p;
seg[rs(now)]=(seg[rs(now)]*multag[now]+addtag[now]*(r-mid))%p;
multag[ls(now)]=(multag[ls(now)]*multag[now])%p;
multag[rs(now)]=(multag[rs(now)]*multag[now])%p;
addtag[ls(now)]=(addtag[ls(now)]*multag[now]+addtag[now])%p;
addtag[rs(now)]=(addtag[rs(now)]*multag[now]+addtag[now])%p;
multag[now]=1;
addtag[now]=0;
}
void mulchange(long long now,long long l,long long r,long long a,long long b,long long c)
{
if(r<a||l>b)return;
if(a<=l&&r<=b)
{
seg[now]=(seg[now]*c)%p;
multag[now]=(multag[now]*c)%p;
addtag[now]=(addtag[now]*c)%p;
return;
}
pushdown(now,l,r);
long long mid=(l+r)>>1;
mulchange(ls(now),l,mid,a,b,c);
mulchange(rs(now),mid+1,r,a,b,c);
seg[now]=(seg[ls(now)]+seg[rs(now)])%p;
return;
}
void addchange(long long now,long long l,long long r,long long a,long long b,long long c)
{
if(r<a||l>b)return;
if(l>=a&&r<=b)
{
addtag[now]=(addtag[now]+c)%p;
seg[now]=(seg[now]+c*(r-l+1))%p;
return;
}
pushdown(now,l,r);
long long mid=(l+r)>>1;
addchange(ls(now),l,mid,a,b,c);
addchange(rs(now),mid+1,r,a,b,c);
seg[now]=(seg[ls(now)]+seg[rs(now)])%p;
return;
}
long long query(long long now,long long l,long long r,long long a,long long b)
{
if(r<a||l>b)return 0;
if(l>=a&&r<=b)return seg[now];
pushdown(now,l,r);
long long mid=(l+r)>>1;
return (query(ls(now),l,mid,a,b)+query(rs(now),mid+1,r,a,b))%p;
}
int main()
{
n=kd(),m=kd(),p=kd();
for(register int i=1;i<=n;i++)
{
num[i]=kd();
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
long long pan=kd();
long long a=kd(),b=kd();
if(pan==1)
{
long long c=kd();
mulchange(1,1,n,a,b,c);
}
if(pan==2)
{
long long c=kd();
addchange(1,1,n,a,b,c);
}
if(pan==3)
{
cout<<query(1,1,n,a,b)<<endl;
}
}
return 0;
}