---
tags: codebook
---
# segment tree beats
https://judge.yosupo.jp/problem/range_chmin_chmax_add_range_sum
```cpp=
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define endl '\n'
using namespace std;
using ll=long long;
template<typename T> using V=vector<T>;
constexpr int maxn=200005;
constexpr ll infll=0x3f3f3f3f3f3f3f3f;
struct node{
ll sum,inc,mx,smx,cmx,tmn,mn,smn,cmn,tmx;
node(ll x=0):sum(x),inc(0),mx(x),smx(-infll),cmx(1),tmn(infll),
mn(x),smn(infll),cmn(1),tmx(-infll){}
void pull(int,int);
} arr[(maxn+1)<<2];
#define m ((l+r)>>1)
void node::pull(int l,int r){
sum=cmx=cmn=0,mx=smx=-infll,mn=smn=infll;
for(auto i:{l,r}){
sum+=arr[i].sum;
mx=max(mx,arr[i].mx);
mn=min(mn,arr[i].mn);
}
for(auto i:{l,r}){
if(arr[i].mx==mx)
cmx+=arr[i].cmx;
if(arr[i].mn==mn)
cmn+=arr[i].cmn;
if(arr[i].mn>mn)
smn=min(smn,arr[i].mn);
if(arr[i].smn>mn)
smn=min(smn,arr[i].smn);
if(arr[i].mx<mx)
smx=max(smx,arr[i].mx);
if(arr[i].smx<mx)
smx=max(smx,arr[i].smx);
}
}
void build(V<ll>& v,int i=1,int l=0,int r=maxn){
if((int)v.size()<=l) return;
if(r-l==1){arr[i]=v[l];return;}
build(v,i<<1,l,m),build(v,i<<1|1,m,r);
arr[i].pull(i<<1,i<<1|1);
}
inline void pushinc(int i,ll k,int l,int r){
arr[i].sum+=(r-l)*k;
arr[i].mx+=k,arr[i].mn+=k;
if(arr[i].smx!=-infll) arr[i].smx+=k;
if(arr[i].smn!=infll) arr[i].smn+=k;
if(arr[i].tmx!=infll) arr[i].tmx+=k;
if(arr[i].tmn!=infll) arr[i].tmn+=k;
arr[i].inc+=k;
}
inline void pushmin(int i,ll k){
if(arr[i].mx<=k) return;
arr[i].sum+=(k-arr[i].mx)*arr[i].cmx;
if(arr[i].smn==arr[i].mx) arr[i].smn=k;
if(arr[i].mn==arr[i].mx) arr[i].mn=k;
if(arr[i].tmx>k) arr[i].tmx=k;
arr[i].mx=k,arr[i].tmn=k;
}
inline void pushmax(int i,ll k){
if(arr[i].mn>=k) return;
arr[i].sum+=(k-arr[i].mn)*arr[i].cmn;
if(arr[i].smx==arr[i].mn) arr[i].smx=k;
if(arr[i].mx==arr[i].mn) arr[i].mx=k;
if(arr[i].tmn<k) arr[i].tmn=k;
arr[i].mn=k,arr[i].tmx=k;
}
inline void push(int i,int l,int r){
if(arr[i].inc)
pushinc(i<<1,arr[i].inc,l,m),pushinc(i<<1|1,arr[i].inc,m,r);
if(arr[i].tmx!=-infll) pushmax(i<<1,arr[i].tmx),pushmax(i<<1|1,arr[i].tmx);
if(arr[i].tmn!=infll) pushmin(i<<1,arr[i].tmn),pushmin(i<<1|1,arr[i].tmn);
arr[i].inc=0,arr[i].tmx=-infll,arr[i].tmn=infll;
}
void increase(int ql,int qr,ll k,int i=1,int l=0,int r=maxn){
if(qr<=l||r<=ql) return;
if(ql<=l&&r<=qr) return pushinc(i,k,l,r);
push(i,l,r);
increase(ql,qr,k,i<<1,l,m),increase(ql,qr,k,i<<1|1,m,r);
arr[i].pull(i<<1,i<<1|1);
}
void tomin(int ql,int qr,ll k,int i=1,int l=0,int r=maxn){
if(qr<=l||r<=ql||arr[i].mx<=k) return;
if(ql<=l&&r<=qr&&arr[i].smx<k) return pushmin(i,k);
push(i,l,r);
tomin(ql,qr,k,i<<1,l,m),tomin(ql,qr,k,i<<1|1,m,r);
arr[i].pull(i<<1,i<<1|1);
}
void tomax(int ql,int qr,ll k,int i=1,int l=0,int r=maxn){
if(qr<=l||r<=ql||arr[i].mn>=k) return;
if(ql<=l&&r<=qr&&arr[i].smn>k) return pushmax(i,k);
push(i,l,r);
tomax(ql,qr,k,i<<1,l,m),tomax(ql,qr,k,i<<1|1,m,r);
arr[i].pull(i<<1,i<<1|1);
}
ll query(int ql,int qr,int i=1,int l=0,int r=maxn){
if(qr<=l||r<=ql) return 0;
if(ql<=l&&r<=qr) return arr[i].sum;
push(i,l,r);
return query(ql,qr,i<<1,l,m)+query(ql,qr,i<<1|1,m,r);
}
#undef m
inline void solve(){
int n,q;cin>>n>>q;
V<ll> v(n);
for(auto& i:v)
cin>>i;
build(v);
while(q--){
int op,ql,qr;cin>>op;
ll k;
switch(op){
case 0:{
cin>>ql>>qr>>k;
tomin(ql,qr,k);
}break;
case 1:{
cin>>ql>>qr>>k;
tomax(ql,qr,k);
}break;
case 2:{
cin>>ql>>qr>>k;
increase(ql,qr,k);
}break;
case 3:{
cin>>ql>>qr;
cout<<query(ql,qr)<<endl;
}break;
}
}
}
signed main(){
cin.tie(nullptr)->sync_with_stdio(false);
solve();
return 0;
}
```