传送门
题目描述
如题,已知一个数列,你需要进行下面三种操作:
1.将某区间每一个数乘上x
2.将某区间每一个数加上x
3.求出某区间每一个数的和
输入输出格式
输入格式:第一行包含三个整数N、M、P,分别表示该数列数字的个数、操作的总个数和模数。
第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
接下来M行每行包含3或4个整数,表示一个操作,具体如下:
操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k
操作2: 格式:2 x y k 含义:将区间[x,y]内每个数加上k
操作3: 格式:3 x y 含义:输出区间[x,y]内每个数的和对P取模所得的结果
输出包含若干行整数,即为所有操作3的结果。
AC代码:
#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
const int Maxn=100005;
ll a[Maxn];
struct node{
ll x,c,m;
int l,r;
}t[Maxn*8];
int n,m,mod;
inline int lson(int x){
return x*2;
}
inline int rson(int x){
return x*2+1;
}
inline int pushup(int rt){
t[rt].x=(t[lson(rt)].x+t[rson(rt)].x)%mod;
}
inline void build(int l,int r,int rt){
t[rt].l=l;t[rt].r=r;t[rt].m=1;
if(l==r){
t[rt].x=a[l];
return;
}
int mid=l+r>>1;
build(l,mid,lson(rt));
build(mid+1,r,rson(rt));
pushup(rt);
}
inline int len(int rt){
return t[rt].r-t[rt].l+1;
}
inline void pushdown(int rt){
if(t[rt].l==t[rt].r)return;
if(t[rt].c==0&&t[rt].m==1)return;
t[lson(rt)].m=t[lson(rt)].m*t[rt].m%mod;
t[rson(rt)].m=t[rson(rt)].m*t[rt].m%mod;
t[lson(rt)].x=(t[lson(rt)].x*t[rt].m%mod+t[rt].c*len(lson(rt))%mod)%mod;
t[rson(rt)].x=(t[rson(rt)].x*t[rt].m%mod+t[rt].c*len(rson(rt))%mod)%mod;
t[lson(rt)].c=(t[lson(rt)].c*t[rt].m%mod+t[rt].c)%mod;
t[rson(rt)].c=(t[rson(rt)].c*t[rt].m%mod+t[rt].c)%mod;
t[rt].c=0;t[rt].m=1;
}
inline void update_1(int l,int r,ll x,int rt){
if(t[rt].l>=l&&t[rt].r<=r){
t[rt].x=(t[rt].x+x*len(rt)%mod)%mod;
t[rt].c=(t[rt].c+x)%mod;
return;
}
pushdown(rt);
int mid=t[rt].l+t[rt].r>>1;
if(l<=mid){
update_1(l,r,x,lson(rt));
}
if(r>mid){
update_1(l,r,x,rson(rt));
}
pushup(rt);
}
inline void update_2(int l,int r,ll x,int rt){
if(t[rt].l>=l&&t[rt].r<=r){
t[rt].x=(t[rt].x*x)%mod;
t[rt].m=(t[rt].m*x)%mod;
t[rt].c=(t[rt].c*x)%mod;
return;
}
pushdown(rt);
int mid=t[rt].l+t[rt].r>>1;
if(l<=mid){
update_2(l,r,x,lson(rt));
}
if(r>mid){
update_2(l,r,x,rson(rt));
}
pushup(rt);
}
inline ll query(int l,int r,int rt){
if(t[rt].l>=l&&t[rt].r<=r){
return t[rt].x%mod;
}
pushdown(rt);
int mid=t[rt].l+t[rt].r>>1;ll ans=0;
if(l<=mid){
ans=(ans+query(l,r,lson(rt)))%mod;
}
if(r>mid){
ans=(ans+query(l,r,rson(rt)))%mod;
}
return ans;
}
int main(){
int u,v,inc;ll w;
scanf("%d%d%d",&n,&m,&mod);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,n,1);
while(m--){
scanf("%d%d%d",&inc,&u,&v);
if(inc==1){
scanf("%lld",&w);
update_2(u,v,w,1);
}
if(inc==2){
scanf("%lld",&w);
update_1(u,v,w,1);
}
if(inc==3){
printf("%lld\n",query(u,v,1));
}
}
return 0;
}