P2023,样例过了,全WA
#include<iostream>
using namespace std;
#define lson i<<1
#define rson i<<1|1
#define maxn 100003
#define int unsigned long long
#define upd if (tree[i].sum>=p) tree[i].sum-=p;
struct node{
int l,r,sum,mul,add;
}tree[maxn<<2];
int n,m,a[maxn],p;
void Build(int i,int l,int r){
tree[i].l=l;tree[i].r=r;tree[i].mul=1;
if (l==r){
tree[i].sum=a[l]%p;
// upd;
return;
}
int mid=(l+r)/2;
Build(lson,l,mid);
Build(rson,mid+1,r);
tree[i].sum=(tree[lson].sum+tree[rson].sum)%p;
// upd;
}
void PushDown(int i){
if (tree[i].add){
tree[lson].sum=(tree[lson].sum*tree[i].mul%p + (tree[lson].r-tree[lson].l+1)*tree[i].add%p) %p;
tree[rson].sum=(tree[rson].sum*tree[i].mul%p + (tree[rson].r-tree[rson].l+1)*tree[i].add%p) %p;
tree[lson].mul=tree[lson].mul*tree[i].mul%p;
tree[rson].mul=tree[rson].mul*tree[i].mul%p;
tree[lson].add=(tree[lson].add*tree[i].mul%p+tree[i].add)%p;
tree[rson].add=(tree[rson].add*tree[i].mul%p+tree[i].add)%p;
tree[i].mul=1;
tree[i].add=0;
}
}
void OpMul(int i,int l,int r,int v){
if (tree[i].l>=l&&tree[i].r<=r){
tree[i].sum=(tree[i].sum*v)%p;
//乘法分配律
tree[i].mul=(tree[i].mul*v)%p;
tree[i].add=(tree[i].add*v)%p;
return;
}
PushDown(i);
int mid=(tree[i].l+tree[i].r)/2;
if (l<=mid) OpMul(lson,l,r,v);
if (r>mid) OpMul(rson,l,r,v);
tree[i].sum=(tree[lson].sum+tree[rson].sum)%p;
// upd;
}
void OpAdd(int i,int l,int r,int v){
if (tree[i].l>=l&&tree[i].r<=r){
tree[i].sum=(tree[i].sum+(tree[i].r-tree[i].l+1)*v)%p;
tree[i].add=(tree[i].add+v)%p;
return;
}
PushDown(i);
int mid=(tree[i].l+tree[i].r)/2;
if (l<=mid) {
OpAdd(lson,l,r,v);
}
if (r>mid) {
OpAdd(rson,l,r,v);
}
tree[i].sum=(tree[lson].sum+tree[rson].sum)%p;
// upd;
}
int Query(int i,int l,int r){
if (l<=tree[i].l&&tree[i].r<=r){
return tree[i].sum%p;
}
PushDown(i);
int val=0;
int mid=(tree[i].l+tree[i].r)/2;
if (l<=mid) val=(val+Query(lson,l,r))%p;
if (r>mid) val=(val+Query(rson,l,r))%p;
//tree[i].sum=(tree[lson].sum+tree[rson].sum)%p;
// if (val>=p) val-=p;
// tree[i].sum=(tree[lson].sum+tree[rson].sum);
// upd;
return val;
}
signed main(){
cin>>n>>p;
for (int i=1;i<=n;i++){
cin>>a[i];
}
Build(1,1,n);
cin>>m;
int op,l,r,v;
for (int i=1;i<=m;i++){
cin>>op>>l>>r;
if (op==1){
cin>>v;
OpMul(1,l,r,v);
}
if (op==2){
cin>>v;
OpAdd(1,l,r,v);
}
if (op==3){
cout<<Query(1,l,r)%p<<endl;
}
}
return 0;
}