P3373线段树模板2 阳历过了却0分
#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define ll long long
int n,q,m,k,x,y,mod;
struct tree{
int l,r;
ll sum,add1,add2;
}tr[N*4];
int a[N];
void pushup(int p){
tr[p].sum = (tr[p<<1].sum + tr[p<<1|1].sum)%mod;
}
void pushdown1(int p){
if(tr[p].add1 != 1){
tr[p<<1].add1 *= tr[p].add1;
tr[p<<1|1].add1 *= tr[p].add1;
tr[p<<1].sum = tr[p<<1].sum*tr[p].add1%mod;
tr[p<<1|1].sum += tr[p<<1|1].sum*tr[p].add1%mod;
tr[p].add1 = 1;
}
}
void pushdown2(int p){
if(tr[p].add2){
tr[p<<1].add2 += k;
tr[p<<1|1].add2 += k;
tr[p<<1].sum = (tr[p<<1].sum + (tr[p<<1].r-tr[p<<1].l+1)*tr[p].add2)%mod;
tr[p<<1|1].sum = (tr[p<<1|1].sum+(tr[p<<1|1].r-tr[p<<1|1].l+1)*tr[p].add2)%mod;
tr[p].add2 = 0;
}
}
void build(int p,int l,int r){
tr[p].l = l,tr[p].r = r;
tr[p].add1 = 1;
if(l == r){
tr[p].sum = a[l];
return;
}
int mid = l+r >> 1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void modify1(int p,int l,int r,int k){
if(tr[p].l >= l && tr[p].r <= r){
tr[p].sum = tr[p].sum*k%mod;
tr[p].add1 *= k;
tr[p].add2 += k*tr[p].add2%mod;
pushdown1(p);
return;
}
int mid = tr[p].l + tr[p].r >> 1;
if(l <= mid) modify1(p<<1,l,r,k);
if(r > mid) modify1(p<<1|1,l,r,k);
pushup(p);
}
void modify2(int p,int l,int r,int k){
if(tr[p].l >= l && tr[p].r <= r){
tr[p].sum = (tr[p].sum + (tr[p].r - tr[p].l+1)*k)%mod;
tr[p].add2 += k;
pushdown2(p);
return;
}
int mid = tr[p].l + tr[p].r >> 1;
if(l <= mid) modify2(p<<1,l,r,k);
if(r > mid) modify2(p<<1|1,l,r,k);
pushup(p);
}
ll query(int p,int l,int r){
if(tr[p].l >= l && tr[p].r <= r){
return tr[p].sum;
}
pushdown1(p);
pushdown2(p);
ll res = 0;
int mid = tr[p].l + tr[p].r >> 1;
if(l <= mid) res = (res+query(p<<1,l,r))%mod;
if(r > mid) res = (res+query(p<<1|1,l,r))%mod;
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin >> n >> q >> mod;
for(int i = 1; i <= n; i++) cin >> a[i];
build(1,1,n);
while(q--){
int opt;
cin >> opt;
if(opt == 1){
cin >> x >> y >> k;
modify1(1,x,y,k);
}else if(opt == 2){
cin >> x >> y >> k;
modify2(1,x,y,k);
}else{
cin >> x >> y;
cout << query(1,x,y)<<endl;
}
}
return 0;
}