結果
| 問題 |
No.1234 典型RMQ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-09-18 21:43:33 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 184 ms / 2,000 ms |
| コード長 | 6,224 bytes |
| コンパイル時間 | 2,759 ms |
| コンパイル使用メモリ | 207,200 KB |
| 最終ジャッジ日時 | 2025-01-14 16:44:16 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 27 |
ソースコード
#include <bits/stdc++.h>
#ifdef DEBUG
#include <Mylib/Debug/debug.cpp>
#else
#define dump(...) ((void)0)
#endif
template <typename T, typename U>
bool chmin(T &a, const U &b){
return (a > b ? a = b, true : false);
}
template <typename T, typename U>
bool chmax(T &a, const U &b){
return (a < b ? a = b, true : false);
}
template <typename T, size_t N, typename U>
void fill_array(T (&a)[N], const U &v){
std::fill((U*)a, (U*)(a + N), v);
}
template <typename T, size_t N, size_t I = N>
auto make_vector(const std::array<int, N> &a, T value = T()){
static_assert(I >= 1);
static_assert(N >= 1);
if constexpr (I == 1){
return std::vector<T>(a[N - I], value);
}else{
return std::vector(a[N - I], make_vector<T, N, I - 1>(a, value));
}
}
template <typename T>
std::ostream& operator<<(std::ostream &s, const std::vector<T> &a){
for(auto it = a.begin(); it != a.end(); ++it){
if(it != a.begin()) s << " ";
s << *it;
}
return s;
}
template <typename T>
std::istream& operator>>(std::istream &s, std::vector<T> &a){
for(auto &x : a) s >> x;
return s;
}
namespace haar_lib {
template <typename MonoidGet, typename MonoidUpdate, template <typename, typename> typename Connector>
class lazy_segment_tree {
using value_type_get = typename MonoidGet::value_type;
using value_type_update = typename MonoidUpdate::value_type;
Connector<MonoidGet, MonoidUpdate> M;
MonoidGet M_get;
MonoidUpdate M_update;
const int depth, size, hsize;
std::vector<value_type_get> data;
std::vector<value_type_update> lazy;
void propagate(int i){
if(lazy[i] == M_update()) return;
if(i < hsize){
lazy[i << 1 | 0] = M_update(lazy[i], lazy[i << 1 | 0]);
lazy[i << 1 | 1] = M_update(lazy[i], lazy[i << 1 | 1]);
}
int len = hsize >> (31 - __builtin_clz(i));
data[i] = M(data[i], lazy[i], len);
lazy[i] = M_update();
}
void propagate_top_down(int i){
std::vector<int> temp;
while(i > 1){
i >>= 1;
temp.push_back(i);
}
for(auto it = temp.rbegin(); it != temp.rend(); ++it) propagate(*it);
}
void bottom_up(int i){
while(i > 1){
i >>= 1;
propagate(i << 1 | 0);
propagate(i << 1 | 1);
data[i] = M_get(data[i << 1 | 0], data[i << 1 | 1]);
}
}
public:
lazy_segment_tree(){}
lazy_segment_tree(int n):
depth(n > 1 ? 32 - __builtin_clz(n - 1) + 1 : 1),
size(1 << depth),
hsize(size / 2),
data(size, M_get()),
lazy(size, M_update())
{}
void update(int l, int r, const value_type_update &x){
propagate_top_down(l + hsize);
if(r < hsize) propagate_top_down(r + hsize);
int L = l + hsize, R = r + hsize;
while(L < R){
if(R & 1){
--R;
lazy[R] = M_update(x, lazy[R]);
propagate(R);
}
if(L & 1){
lazy[L] = M_update(x, lazy[L]);
propagate(L);
++L;
}
L >>= 1;
R >>= 1;
}
bottom_up(l + hsize);
if(r < hsize) bottom_up(r + hsize);
}
void update_at(int i, const value_type_update &x){update(i, i + 1, x);}
value_type_get get(int l, int r){
propagate_top_down(l + hsize);
if(r < hsize) propagate_top_down(r + hsize);
value_type_get ret_left = M_get(), ret_right = M_get();
int L = l + hsize, R = r + hsize;
while(L < R){
if(R & 1){
--R;
propagate(R);
ret_right = M_get(data[R], ret_right);
}
if(L & 1){
propagate(L);
ret_left = M_get(ret_left, data[L]);
++L;
}
L >>= 1;
R >>= 1;
}
return M_get(ret_left, ret_right);
}
value_type_get operator[](int i){return get(i, i + 1);}
template <typename T>
void init(const T &val){
init_with_vector(std::vector<T>(hsize, val));
}
template <typename T>
void init_with_vector(const std::vector<T> &val){
data.assign(size, M_get());
lazy.assign(size, M_update());
for(int i = 0; i < (int)val.size(); ++i) data[hsize + i] = val[i];
for(int i = hsize - 1; i > 0; --i) data[i] = M_get(data[i << 1 | 0], data[i << 1 | 1]);
}
};
}
namespace haar_lib {
template <typename T>
struct min_monoid {
using value_type = std::optional<T>;
value_type operator()() const {return {};}
value_type operator()(const value_type &a, const value_type &b) const {
if(not a) return b;
if(not b) return a;
return {std::min(*a, *b)};
}
};
}
namespace haar_lib {
template <typename T>
struct sum_monoid {
using value_type = T;
value_type operator()() const {return 0;}
value_type operator()(value_type a, value_type b) const {return a + b;}
};
}
namespace haar_lib {
template <typename MonoidGet, typename MonoidUpdate>
struct add_min {
using value_type_get = typename MonoidGet::value_type;
using value_type_update = typename MonoidUpdate::value_type;
value_type_get operator()(value_type_get a, value_type_update b, int) const {
if(a) return {*a + b};
return {};
}
};
}
namespace haar_lib {}
namespace solver {
using namespace haar_lib;
constexpr int m1000000007 = 1000000007;
constexpr int m998244353 = 998244353;
void init(){
std::cin.tie(0);
std::ios::sync_with_stdio(false);
std::cout << std::fixed << std::setprecision(12);
std::cerr << std::fixed << std::setprecision(12);
std::cin.exceptions(std::ios_base::failbit);
}
void solve(){
int N; std::cin >> N;
std::vector<int64_t> a(N); std::cin >> a;
auto seg = lazy_segment_tree<min_monoid<int64_t>, sum_monoid<int64_t>, add_min>(N);
seg.init_with_vector(a);
int Q; std::cin >> Q;
while(Q--){
int k; std::cin >> k;
int l, r, c; std::cin >> l >> r >> c;
--l;
if(k == 1){
seg.update(l, r, c);
}else{
std::cout << seg.get(l, r).value() << "\n";
}
}
}
}
int main(){
solver::init();
while(true){
try{
solver::solve();
}catch(const std::istream::failure &e){
break;
}
}
return 0;
}