→题目链接←
【想说的话】
又是一道题解泛滥的题
【题解】
裸线段树,注意乘的时候加的标记也要乘,传标记时要乘一下
看代码吧...
【代码】
#include<bits/stdc++.h>
#define inf 1000000000
#define MAXN 100005
typedef long long ll;
using namespace std;
inline int rd(){
int x=0,y=1;char c=getchar();
while(c<'0' || c>'9'){if(c=='-')y=-y;c=getchar();}
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x*y;
}
struct node{
int l,r,len,mid;
ll sum,mul,add;
}tree[MAXN*4];
int n,mod,ans,num;
void push_up(int x){
tree[x].sum=(tree[x*2].sum+tree[x*2+1].sum)%mod;
}
void build(int x,int l,int r){
tree[x].l=l;
tree[x].r=r;
tree[x].len=r-l+1;
tree[x].mid=(l+r)/2;
tree[x].add=0;
tree[x].mul=1;
if(l==r){
tree[x].sum=rd();
return;
}
build(x*2,l,tree[x].mid);
build(x*2+1,tree[x].mid+1,r);
push_up(x);
}
void push_down(int x){
tree[x*2].add=(tree[x*2].add*tree[x].mul+tree[x].add)%mod;
tree[x*2+1].add=(tree[x*2+1].add*tree[x].mul+tree[x].add)%mod;
tree[x*2].mul=tree[x*2].mul*tree[x].mul%mod;
tree[x*2+1].mul=tree[x*2+1].mul*tree[x].mul%mod;
tree[x*2].sum=(tree[x*2].sum*tree[x].mul%mod+tree[x].add*tree[x*2].len%mod)%mod;
tree[x*2+1].sum=(tree[x*2+1].sum*tree[x].mul%mod+tree[x].add*tree[x*2+1].len%mod)%mod;
tree[x].mul=1;
tree[x].add=0;
}
ll query(int x,int l,int r){
if(tree[x].l>=l && tree[x].r<=r){
return tree[x].sum%mod;
}
push_down(x);
if(r<=tree[x].mid)return query(x*2,l,r);
else if(l>tree[x].mid)return query(x*2+1,l,r);
else return (query(x*2,l,tree[x].mid)+query(x*2+1,tree[x].mid+1,r))%mod;
}
void update(int x,int l,int r,int k){
if(tree[x].l>=l && tree[x].r<=r){
if(k==1){
tree[x].add=tree[x].add*num%mod;
tree[x].mul=tree[x].mul*num%mod;
tree[x].sum=tree[x].sum*num%mod;
}
else{
tree[x].add=(tree[x].add+num)%mod;
tree[x].sum=(tree[x].sum+(ll)num*tree[x].len%mod)%mod;
}
return;
}
push_down(x);
if(r<=tree[x].mid)update(x*2,l,r,k);
else if(l>tree[x].mid)update(x*2+1,l,r,k);
else update(x*2,l,tree[x].mid,k),update(x*2+1,tree[x].mid+1,r,k);
push_up(x);
}
int main(){
n=rd(),mod=rd();
build(1,1,n);
int m=rd();
while(m--){
int x=rd(),y=rd(),z=rd();
if(x==3)printf("%lld\n",query(1,y,z));
else{
num=rd();
update(1,y,z,x);
}
}
return 0;
}