konchin_shih

segment tree beats

Sep 15th, 2022 (edited)
920
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.72 KB | None | 0 0
  1. #include<iostream>
  2. #include<algorithm>
  3. #include<queue>
  4. #include<vector>
  5. #define endl '\n'
  6. using namespace std;
  7. using ll=long long;
  8. template<typename T> using V=vector<T>;
  9. constexpr int maxn=200005;
  10. constexpr ll infll=0x3f3f3f3f3f3f3f3f;
  11. struct node{
  12.     ll sum,inc,mx,smx,cmx,tmn,mn,smn,cmn,tmx;
  13.     node(ll x=0):sum(x),inc(0),mx(x),smx(-infll),cmx(1),tmn(infll),
  14.         mn(x),smn(infll),cmn(1),tmx(-infll){}
  15.     void pull(int,int);
  16. } arr[(maxn+1)<<2];
  17. #define m ((l+r)>>1)
  18. void node::pull(int l,int r){
  19.     sum=cmx=cmn=0,mx=smx=-infll,mn=smn=infll;
  20.     for(auto i:{l,r}){
  21.         sum+=arr[i].sum;
  22.         mx=max(mx,arr[i].mx);
  23.         mn=min(mn,arr[i].mn);
  24.     }
  25.     for(auto i:{l,r}){
  26.         if(arr[i].mx==mx)
  27.             cmx+=arr[i].cmx;
  28.         if(arr[i].mn==mn)
  29.             cmn+=arr[i].cmn;
  30.         if(arr[i].mn>mn)
  31.             smn=min(smn,arr[i].mn);
  32.         if(arr[i].smn>mn)
  33.             smn=min(smn,arr[i].smn);
  34.         if(arr[i].mx<mx)
  35.             smx=max(smx,arr[i].mx);
  36.         if(arr[i].smx<mx)
  37.             smx=max(smx,arr[i].smx);
  38.     }
  39. }
  40. void build(V<ll>& v,int i=1,int l=0,int r=maxn){
  41.     if((int)v.size()<=l) return;
  42.     if(r-l==1){arr[i]=v[l];return;}
  43.     build(v,i<<1,l,m),build(v,i<<1|1,m,r);
  44.     arr[i].pull(i<<1,i<<1|1);
  45. }
  46. inline void pushinc(int i,ll k,int l,int r){
  47.     arr[i].sum+=(r-l)*k;
  48.     arr[i].mx+=k,arr[i].mn+=k;
  49.     if(arr[i].smx!=-infll) arr[i].smx+=k;
  50.     if(arr[i].smn!=infll) arr[i].smn+=k;
  51.     if(arr[i].tmx!=infll) arr[i].tmx+=k;
  52.     if(arr[i].tmn!=infll) arr[i].tmn+=k;
  53.     arr[i].inc+=k;
  54. }
  55. inline void pushmin(int i,ll k){
  56.     if(arr[i].mx<=k) return;
  57.     arr[i].sum+=(k-arr[i].mx)*arr[i].cmx;
  58.     if(arr[i].smn==arr[i].mx) arr[i].smn=k;
  59.     if(arr[i].mn==arr[i].mx) arr[i].mn=k;
  60.     if(arr[i].tmx>k) arr[i].tmx=k;
  61.     arr[i].mx=k,arr[i].tmn=k;
  62. }
  63. inline void pushmax(int i,ll k){
  64.     if(arr[i].mn>=k) return;
  65.     arr[i].sum+=(k-arr[i].mn)*arr[i].cmn;
  66.     if(arr[i].smx==arr[i].mn) arr[i].smx=k;
  67.     if(arr[i].mx==arr[i].mn) arr[i].mx=k;
  68.     if(arr[i].tmn<k) arr[i].tmn=k;
  69.     arr[i].mn=k,arr[i].tmx=k;
  70. }
  71. inline void push(int i,int l,int r){
  72.     if(arr[i].inc)
  73.         pushinc(i<<1,arr[i].inc,l,m),pushinc(i<<1|1,arr[i].inc,m,r);
  74.     if(arr[i].tmx!=-infll) pushmax(i<<1,arr[i].tmx),pushmax(i<<1|1,arr[i].tmx);
  75.     if(arr[i].tmn!=infll) pushmin(i<<1,arr[i].tmn),pushmin(i<<1|1,arr[i].tmn);
  76.     arr[i].inc=0,arr[i].tmx=-infll,arr[i].tmn=infll;
  77. }
  78. void increase(int ql,int qr,ll k,int i=1,int l=0,int r=maxn){
  79.     if(qr<=l||r<=ql) return;
  80.     if(ql<=l&&r<=qr) return pushinc(i,k,l,r);
  81.     push(i,l,r);
  82.     increase(ql,qr,k,i<<1,l,m),increase(ql,qr,k,i<<1|1,m,r);
  83.     arr[i].pull(i<<1,i<<1|1);
  84. }
  85. void tomin(int ql,int qr,ll k,int i=1,int l=0,int r=maxn){
  86.     if(qr<=l||r<=ql||arr[i].mx<=k) return;
  87.     if(ql<=l&&r<=qr&&arr[i].smx<k) return pushmin(i,k);
  88.     push(i,l,r);
  89.     tomin(ql,qr,k,i<<1,l,m),tomin(ql,qr,k,i<<1|1,m,r);
  90.     arr[i].pull(i<<1,i<<1|1);
  91. }
  92. void tomax(int ql,int qr,ll k,int i=1,int l=0,int r=maxn){
  93.     if(qr<=l||r<=ql||arr[i].mn>=k) return;
  94.     if(ql<=l&&r<=qr&&arr[i].smn>k) return pushmax(i,k);
  95.     push(i,l,r);
  96.     tomax(ql,qr,k,i<<1,l,m),tomax(ql,qr,k,i<<1|1,m,r);
  97.     arr[i].pull(i<<1,i<<1|1);
  98. }
  99. ll query(int ql,int qr,int i=1,int l=0,int r=maxn){
  100.     if(qr<=l||r<=ql) return 0;
  101.     if(ql<=l&&r<=qr) return arr[i].sum;
  102.     push(i,l,r);
  103.     return query(ql,qr,i<<1,l,m)+query(ql,qr,i<<1|1,m,r);
  104. }
  105. #undef m
  106. inline void solve(){
  107.     int n,q;cin>>n>>q;
  108.     V<ll> v(n);
  109.     for(auto& i:v)
  110.         cin>>i;
  111.     build(v);
  112.     while(q--){
  113.         int op,ql,qr;cin>>op;
  114.         ll k;
  115.         switch(op){
  116.         case 0:{
  117.             cin>>ql>>qr>>k;
  118.             tomin(ql,qr,k);
  119.         }break;
  120.         case 1:{
  121.             cin>>ql>>qr>>k;
  122.             tomax(ql,qr,k);
  123.         }break;
  124.         case 2:{
  125.             cin>>ql>>qr>>k;
  126.             increase(ql,qr,k);
  127.         }break;
  128.         case 3:{
  129.             cin>>ql>>qr;
  130.             cout<<query(ql,qr)<<endl;
  131.         }break;
  132.         }
  133.     }
  134. }
  135. signed main(){
  136.     cin.tie(nullptr)->sync_with_stdio(false);
  137.     solve();
  138.     return 0;
  139. }
Advertisement
Add Comment
Please, Sign In to add comment