Line segment tree template 2
Main idea: Two marks addmul, add means add after multiplying mul, current add and current mul are independent main idea: two marks add mul, add means add after multiplying mul, current The add and the current mul are independentThe main idea : two marks a d d m u l , a d d means a d d that has been multiplied by m u l , the current a d d and the current m u l are independent _
current is addmul current is add mulThe current is a d d m u l
when the interval + c, -> add + c , mul when the interval + c, -> add+c,mulwhen the interval+When c , −>add+c,m u l
When the interval ∗ c, −> add ∗ c , mul ∗ c When the interval *c, -> add*c,mul *cwhen the interval∗When c , −>add∗c,m u l∗c
#include <stdio.h>
#include <iostream>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
int N,M,mod;
int a[maxn];
struct Seg{
#define lson u<<1
#define rson u<<1|1
struct node{
int l,r;
ll add,mul,sum;//标记加,标记乘,区间和
}tr[maxn*4];
void pushup(node &U,node& L,node& R){
U.sum = (L.sum + R.sum)%mod;
}
void build(int u,int l,int r){
tr[u] = {
l,r,0,1,a[l]};
if(l == r){
return ;
}else{
int mid = (l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(tr[u],tr[lson],tr[rson]);
}
}
void pushdown(node &U,node &L,node &R){
L.sum = (L.sum * U.mul%mod + (L.r - L.l + 1) * U.add%mod) %mod;
R.sum = (R.sum * U.mul%mod + (R.r - R.l + 1) * U.add%mod) %mod;
L.add = (L.add * U.mul %mod + U.add)%mod;
R.add = (R.add * U.mul %mod + U.add)%mod;
L.mul = (L.mul * U.mul)%mod;
R.mul = (R.mul * U.mul)%mod;
U.add = 0;
U.mul = 1;
}
void add(int u,int l,int r,int v){
if(l <= tr[u].l && tr[u].r <= r){
tr[u].sum = (tr[u].sum + v * (tr[u].r-tr[u].l+1)%mod) %mod;
tr[u].add = (tr[u].add + v )%mod;
}else{
pushdown(tr[u],tr[lson],tr[rson]);
int mid = (tr[u].l + tr[u].r)>>1;
if(l <= mid) add(lson,l,r,v);
if(r > mid) add(rson,l,r,v);
pushup(tr[u],tr[lson],tr[rson]);
}
}
void mul(int u,int l,int r,int v){
if(l<= tr[u].l && tr[u].r <= r){
tr[u].sum = (tr[u].sum) * v%mod;
tr[u].mul = (tr[u].mul * v)%mod;
tr[u].add = (tr[u].add * v)%mod;
}else{
pushdown(tr[u],tr[lson],tr[rson]);
int mid = (tr[u].l + tr[u].r)>>1;
if(l<=mid) mul(lson,l,r,v);
if(r>mid) mul(rson,l,r,v);
pushup(tr[u],tr[lson],tr[rson]);
}
}
node query(int u,int l,int r){
if(l <= tr[u].l && tr[u].r <= r){
return tr[u];
}else{
pushdown(tr[u],tr[lson],tr[rson]);
int mid = (tr[u].l + tr[u].r)>>1;
if(r<=mid) return query(lson,l,r);
else if(l>mid) return query(rson,l,r);
else{
node ans1 = query(lson,l,r);
node ans2 = query(rson,l,r);
node ans;
pushup(ans,ans1,ans2);
return ans;
}
}
}
}seg;
int main(){
cin>>N>>M>>mod;
for(int i = 1;i<=N;i++) scanf("%d",&a[i]);
seg.build(1,1,N);
while(M--){
int op,x,y;scanf("%d %d %d",&op,&x,&y);
if(op == 1){
int k;scanf("%d",&k);
seg.mul(1,x,y,k);
}
if(op == 2){
int k;scanf("%d",&k);
seg.add(1,x,y,k);
}
if(op == 3){
Seg::node ans = seg.query(1,x,y);
printf("%lld\n",ans.sum);
}
}
return 0;
}