#include<bits/stdc++.h>
using namespace std;
const int N=200100;
struct node{
int l,r;
long long sum,addv,mul;
}tree[N*4];
int n,mod,m;
int w[N];
void eval(int k,int addv,int mul){
tree[k].addv=(tree[k].addv*mul+addv)%mod;
tree[k].mul=(tree[k].mul*mul)%mod;
tree[k].sum=(tree[k].sum*mul+(tree[k].r-tree[k].l+1)*addv)%mod;
}
void pushdown(int k){
eval(k<<1,tree[k].addv,tree[k].mul);
eval(k<<1|1,tree[k].addv,tree[k].mul);
tree[k].addv=0;
tree[k].mul=1;
}
void pushup(int k){
tree[k].sum=(tree[k<<1].sum+tree[k<<1|1].sum)%mod;
}
void build(int k,int l,int r){
tree[k]={l,r,w[r],0,1};
if(l==r)return ;
int mid=(l+r)/2;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}
void modify(int k,int l,int r,int add,int mul){
if(tree[k].l>=l&&tree[k].r<=r){
eval(k,add,mul);
return ;
}
pushdown(k);
int mid=(tree[k].l+tree[k].r)/2;
if(l<=mid)modify(k<<1,l,r,add,mul);
if(r>mid)modify(k<<1|1,l,r,add,mul);
pushup(k);
}
long long query(int k,int l,int r){
long long ans=0;
if(tree[k].l>=l&&tree[k].r<=r){
return tree[k].sum;
}
pushdown(k);
int mid=(tree[k].l+tree[k].r)/2;
if(l<=mid)ans=ans+query(k<<1,l,r)%mod;
if(r>mid)ans=ans+query(k<<1|1,l,r)%mod;
return ans;
}
int main(){
scanf("%d%d",&n,&mod);
for(int i=1;i<=n;i++)scanf("%d", &w[i]);
build(1,1,n);
scanf("%d",&m);
while(m--){
int t,l,r,d;
scanf("%d%d%d",&t,&l,&r);
if(t==1){
scanf("%d",&d);
modify(1,l,r,0,d);
}else if(t==2){
scanf("%d",&d);
modify(1,l,r,d,1);
}else printf("%d\n",query(1, l, r)%mod);
}
return 0;
}
这个是区间加和乘,有没有大佬帮忙看看怎么再在里面塞一个求最值QAQ