传送门
题目描述
如题,已知一个数列,你需要进行下面三种操作:
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; }