--- 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; } ```