bzoj 1798 Seq 维护序列seq —— 线段树

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
typedef long long ll;
int const xn=1e5+5;
int n,a[xn],cnt,ls[xn<<1],rs[xn<<1],sum[xn<<1],lzy[xn<<1],ml[xn<<1],p;
int rd()
{
int ret=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
return f?ret:-ret;
}
int upt(int x){while(x>=p)x-=p; while(x<0)x+=p; return x;}
void build(int x,int l,int r)
{
ml[x]=1;//
if(l==r){sum[x]=a[l]; return;}
ls[x]=++cnt; rs[x]=++cnt;
build(ls[x],l,mid); build(rs[x],mid+1,r);
sum[x]=upt(sum[ls[x]]+sum[rs[x]]);
}
void turn(int x,int c){sum[x]=(ll)sum[x]*c%p; lzy[x]=(ll)lzy[x]*c%p; ml[x]=(ll)ml[x]*c%p;}
void pushdown(int x,int l,int r)
{
if(ml[x]!=1)//0
{
int v=ml[x]; ml[x]=1;//1
turn(ls[x],v); turn(rs[x],v);
}
if(lzy[x])
{
int v=lzy[x]; lzy[x]=0;
sum[ls[x]]=(sum[ls[x]]+(ll)(mid-l+1)*v)%p; lzy[ls[x]]=upt(lzy[ls[x]]+v);
sum[rs[x]]=(sum[rs[x]]+(ll)(r-mid)*v)%p; lzy[rs[x]]=upt(lzy[rs[x]]+v);
}
}
void mul(int x,int l,int r,int L,int R,int c)
{
if(l>=L&&r<=R){turn(x,c); return;}
pushdown(x,l,r);
if(mid>=L)mul(ls[x],l,mid,L,R,c);
if(mid<R)mul(rs[x],mid+1,r,L,R,c);
sum[x]=upt(sum[ls[x]]+sum[rs[x]]);
}
void add(int x,int l,int r,int L,int R,int c)
{
if(l>=L&&r<=R){sum[x]=(sum[x]+(ll)(r-l+1)*c)%p; lzy[x]=upt(lzy[x]+c); return;}
pushdown(x,l,r);
sum[x]=upt(sum[ls[x]]+sum[rs[x]]);
}
int query(int x,int l,int r,int L,int R)
{
if(l>=L&&r<=R)return sum[x];
pushdown(x,l,r); int ret=0;
if(mid>=L)ret=upt(ret+query(ls[x],l,mid,L,R));
if(mid<R)ret=upt(ret+query(rs[x],mid+1,r,L,R));
return ret;
}
int main()
{
n=rd(); p=rd();
for(int i=1;i<=n;i++)a[i]=rd()%p;
build(++cnt,1,n);
int m=rd();
for(int i=1,tp,l,r,c;i<=m;i++)
{
tp=rd(); l=rd(); r=rd();
if(tp==1)c=rd()%p,mul(1,1,n,l,r,c);
}