結果
問題 | No.1234 典型RMQ |
ユーザー |
![]() |
提出日時 | 2020-09-18 21:46:26 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 340 ms / 2,000 ms |
コード長 | 3,767 bytes |
コンパイル時間 | 2,019 ms |
コンパイル使用メモリ | 175,760 KB |
実行使用メモリ | 7,168 KB |
最終ジャッジ日時 | 2024-11-09 01:46:37 |
合計ジャッジ時間 | 10,024 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 27 |
ソースコード
#include <bits/stdc++.h>using namespace std;// RMQ + range_addstruct RMQ {using value_type = long long;static value_type id() { return 1e18; }static value_type op(const value_type &l, const value_type &r) {return std::min(l, r);}};// LeftHandSidestruct LazyEval {using value_type = long long;static value_type op(const value_type &l, const value_type &r) { return l + r; }};struct RangeUpdateRMQ {using Monoid = RMQ;using Update = LazyEval;using value_type = typename Monoid::value_type;using update_type = typename Update::value_type;static value_type evaluate(const update_type &update, const value_type &r) {return update + r;}};int log2ceil(int n) {--n;n |= n >> 16;n |= n >> 8;n |= n >> 4;n |= n >> 2;n |= n >> 1;return n + 1;}template<typename Struct>class SegmentTreeLazy {public:using Monoid = typename Struct::Monoid;using Update = typename Struct::Update;using value_type = typename Struct::value_type;using update_type = typename Struct::update_type;private:const int n;std::vector<value_type> data;std::vector<update_type> lazy;std::vector<bool> flag;void lazyset(int node, const update_type &update) {if (node < n) {if (flag[node]) {lazy[node] = Update::op(update, lazy[node]);} else {lazy[node] = update;flag[node] = true;}}data[node] = Struct::evaluate(update, data[node]);}void evaluate(int node) {if (!flag[node]) return;flag[node] = false;lazyset(node * 2 + 0, lazy[node]);lazyset(node * 2 + 1, lazy[node]);}void update_sub(int l, int r, int node, int lb, int ub,const update_type &update) {if (ub <= l || r <= lb) {return;}if (l <= lb && ub <= r) {lazyset(node, update);return;}evaluate(node);const int mid = (lb + ub) / 2;update_sub(l, r, node * 2 + 0, lb, mid, update);update_sub(l, r, node * 2 + 1, mid, ub, update);data[node] = Monoid::op(data[node * 2 + 0], data[node * 2 + 1]);}value_type query_sub(int l, int r, int node, int lb, int ub) {if (ub <= l || r <= lb) return Monoid::id();if (l <= lb && ub <= r) {return data[node];}evaluate(node);const int mid = (lb + ub) / 2;value_type lval = query_sub(l, r, node * 2 + 0, lb, mid);value_type rval = query_sub(l, r, node * 2 + 1, mid, ub);return Monoid::op(lval, rval);}public:SegmentTreeLazy(int count, const value_type &init = Monoid::id()) :n(log2ceil(count)), data(n * 2), lazy(n), flag(n, false) {fill(begin(data) + n, end(data), init);for (int i = n - 1; i >= 1; i--) {data[i] = Monoid::op(data[i * 2 + 0], data[i * 2 + 1]);}};void update(int l, int r, const update_type &f) {update_sub(l, r, 1, 0, n, f);}value_type query(int l, int r) {return query_sub(l, r, 1, 0, n);}};int main() {int N;cin >> N;vector<long long> A(N);for (int i = 0; i < N; i++) {cin >> A[i];}SegmentTreeLazy<RangeUpdateRMQ> lazy(N, 0);for (int i = 0; i < N; i++) lazy.update(i, i + 1, A[i]);int Q;cin >> Q;for (int i = 0; i < Q; i++) {int k, l, r, c;cin >> k >> l >> r >> c;--l;if (k == 1) {lazy.update(l, r, c);} else {cout << lazy.query(l, r) << endl;}}}