注:还没有看题解,思路可能不符合常规
思路: 将v设为累加和,lazy1设为累计拦截的增加量,lazy2设为累计拦截的相乘量,并默认先执行相乘再执行相加(并由此进行一定特殊修改)。函数change是相乘,函数add是相加。
然后出的数不对,调试的时候出了数值在未操作下改变的bugDEV特性,重启没有作用。
code
#include<iostream>
#include<cstdio>
#define LL long long
using namespace std;
const int maxn=1e5+10;
int n,m,p;LL a[maxn];
struct node{int l,r;LL v,lazy1,lazy2;}f[4*maxn];
LL k(LL x,LL y){//x^y
LL rt=0;
for(;y;y>>=1,x=x*x%p)
if(y&1) rt=(rt*x)%p;
return rt;
}
void pushup(int t){f[t].v=(f[t<<1].v+f[t<<1|1].v)%p;}
void pushdown(int t){
int l1=f[t<<1].r-f[t<<1].l+1,l2=f[t<<1|1].r-f[t<<1|1].l+1;
f[t<<1].v=(f[t<<1].v*k(f[t].lazy2,l1))%p;
f[t<<1|1].v=(f[t<<1|1].v*k(f[t].lazy2,l2))%p;
f[t<<1].v=(f[t<<1].v+l1*f[t].lazy1)%p;
f[t<<1|1].v=(f[t<<1|1].v+l2*f[t].lazy1)%p;
if(f[t].l==f[t].r){f[t].lazy1=f[t].lazy2=0;return;}
f[t<<1].lazy2=(f[t<<1].lazy2*f[t].lazy2)%p;
f[t<<1|1].lazy2=(f[t<<1|1].lazy2*f[t].lazy2)%p;
f[t<<1].lazy1=(f[t<<1].lazy1*f[t].lazy2)%p;
f[t<<1|1].lazy1=(f[t<<1|1].lazy1*f[t].lazy2)%p;
f[t<<1].lazy1=(f[t<<1].lazy1+f[t].lazy1)%p;
f[t<<1|1].lazy1=(f[t<<1|1].lazy1+f[t].lazy1)%p;
f[t].lazy1=f[t].lazy2=0;
return;
}
void build(int t,int l,int r){
f[t].l=l,f[t].r=r;
if(l==r){f[t].v=a[l];return;}
int m=(l+r)/2;
build(t<<1,l,m),build(t<<1|1,m+1,r);
pushup(t);return;
}
void add(int t,int ul,int ur,LL x){
int l=f[t].l,r=f[t].r;
if(l==r){f[t].v=(f[t].v+x)%p;return;}
if(ul<=l&&r<=ur){
f[t].v=(f[t].v+x*(r-l+1))%p;
f[t].lazy1=(f[t].lazy1+x)%p;
return;
}
pushdown(t);int m=(l+r)/2;
if(ul<=m) add(t<<1,ul,ur,x);
if(m<ur) add(t<<1|1,ul,ur,x);
pushup(t);return;
}
void change(int t,int ul,int ur,LL x){
int l=f[t].l,r=f[t].r;
if(l==r){f[t].v=(f[t].v*x)%p;return;}
if(ul<=l&&r<=ur){
f[t].v=f[t].v*k(x,r-l+1)%p;
f[t].lazy2=f[t].lazy2*x%p;
f[t].lazy1=f[t].lazy1*x%p;
return;
}
pushdown(t);int m=(l+r)/2;
if(ul<=m) add(t<<1,ul,ur,x);
if(m<ur) add(t<<1|1,ul,ur,x);
pushup(t);return;
}
LL getsum(int t,int ul,int ur){
int l=f[t].l,r=f[t].r;
if(ul<=l&&r<=ur) return f[t].v;
pushdown(t);int m=(l+r)/2;LL rt=0;
if(ul<=m) rt=(rt+getsum(t<<1,ul,ur))%p;
if(ur>m) rt=(rt+getsum(t<<1|1,ul,ur))%p;
return rt;
}
void ts(){
for(int i=1;i<=2*n;i++)
printf("%d:%d,%d %lld,%lld %lld\n",i,f[i].l,f[i].r,f[i].lazy1,f[i].lazy2,f[i].v);
}
int main(){
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
ts();
while(m--){
int t,x,y;LL u;scanf("%d%d%d",&t,&x,&y);
if(t==3) printf("%lld\n",getsum(1,x,y));
else{scanf("%lld",&u);u%=p;}
if(t==2) add(1,x,y,u);
if(t==1) change(1,x,y,u);
ts();
}
return 0;
}