- min_left, max_rightの使用例です
- Quora Programming Challenge 2021のSkyscraperという問題で使用してACを確認した
Skyscraper
input
8 6
4 2 3 2 4 7 6 5
1 3
1 2
2 3 8
1 5
3 5 7 1
1 8
output
3
1
2
5
input, output コメントつき
// input
8 6
4 2 3 2 4 7 6 5
// クエリ
1 3 // 建物3から見える建物の数は?
1 2
2 3 8 // 建物3の高さを8にする
1 5
3 5 7 1 // 建物5~7の高さを1にする
1 8
// output
3
1
2
5
全てのクエリを終えた時の建物の状態
AC code
#ifdef LOCAL
#define _GLIBCXX_DEBUG
#define __clock__
#else
#pragma GCC optimize("Ofast")
#endif
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using VI = vector<ll>;
using VV = vector<VI>;
using VS = vector<string>;
using PII = pair<ll, ll>;
#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define rep(i,b) FOR(i, 0, b)
#define ALL(v) (v).begin(), (v).end()
#define p(s) cout<<(s)<<'\n'
#define p2(s, t) cout << (s) << " " << (t) << '\n'
#define br() p("")
#define pn(s) cout << (#s) << " " << (s) << '\n'
#define SZ(x) ((int)(x).size())
#define SORT(A) sort(ALL(A))
#define RSORT(A) sort(ALL(A), greater<ll>())
const ll mod = 1e9 + 7;
const ll inf = 1e18;
const double PI = acos(-1);
#include <atcoder/lazysegtree>
using namespace atcoder;
using S = long long;
using F = long long;
const S INF = 8e18;
const F ID = 8e18;
S op(S a, S b){ return std::max(a, b); }
S e(){ return -INF; }
S mapping(F f, S x){ return (f == ID ? x : f); }
F composition(F f, F g){ return (f == ID ? g : f); }
F id(){ return ID; }
ll global_h;
bool g(S x){
return x <= global_h;
}
int main(){
cin.tie(0);
ios::sync_with_stdio(false);
ll N,Q;cin>>N>>Q;
VI A(N);
rep(i,N)cin>>A[i];
lazy_segtree<S, op, e, F, mapping, composition, id> seg(A);
while(Q--){
ll ty;cin>>ty;
if(ty==1){
ll i;cin>>i;i--;
ll h = seg.get(i);
global_h = h;
ll r = seg.max_right<g>(i);
ll l = seg.min_left<g>(i);
ll cnt = r-l;
p(cnt);
}
else if(ty==2){
ll i;cin>>i;i--;
ll h;cin>>h;
seg.set(i,h);
}
else{
ll i,j,h;cin>>i>>j>>h;
i--;j--;
seg.apply(i,j+1,h);
}
}
return 0;
}