From e71698cfd969c1bdb520bc4a6fe29f15fc9e5795 Mon Sep 17 00:00:00 2001 From: maspypy Date: Mon, 6 Jan 2025 05:22:03 +0900 Subject: [PATCH 1/2] remove bug(unused) code --- .../range_chmin_chmax_add_range_sum/hash.json | 14 +- .../sol/correct.cpp | 497 ++++++++---------- 2 files changed, 239 insertions(+), 272 deletions(-) diff --git a/data_structure/range_chmin_chmax_add_range_sum/hash.json b/data_structure/range_chmin_chmax_add_range_sum/hash.json index 39d2f18c5..e118d3f26 100644 --- a/data_structure/range_chmin_chmax_add_range_sum/hash.json +++ b/data_structure/range_chmin_chmax_add_range_sum/hash.json @@ -13,12 +13,6 @@ "medium_01.out": "e1bfa5ca74fbefd6610dbfd2242808875b8df3fe0caa6770701986c0905dd47b", "medium_02.in": "c6f6af721973a3770f765aac130a13b87ea62a2208078dfcbcb15f6326d15477", "medium_02.out": "179fa759d150c55cc92ccfb1cb4377a1ca99415cf685c42521e2d43eb2fa0ace", - "random_00.in": "fdf3d70976723693e81019bace27a5694f56725bc95ae5b0a54c63887cc2e3c6", - "random_00.out": "fc5728ed5c7cd451f4aa0ce60ff24688ada311eece10a254c2797f18a023629b", - "random_01.in": "77be302a7b07d1f9c55cb0e43fd502af30ecbe7ee013db0a5a27100387d95542", - "random_01.out": "560440fc1763a2c44a80555370c6b8c01175d5f545704ef2f631892160df0a0f", - "random_02.in": "4d947107466ca1262678bf707a0a7d6cfe3c6feeb412b5e0ae8f54248c22f0fe", - "random_02.out": "b4700d13397e89912b98d47d8de387d4c8dff791aca67251b3a888fb246e54be", "random2_00.in": "89dd7acda69f6afef34660348554f53f9e520357a5e345c1c46272f10249e622", "random2_00.out": "87c726bedd90dd045331d4a7079abdeb320ac9fc3a6c3396047621dbf8dcbc67", "random2_01.in": "2faf4bcd81f5da7f477272ebce2acbf474cad9b55e7062393ad77a6444a13101", @@ -31,6 +25,12 @@ "random3_01.out": "34815b7f765aad291da9757efe5a6e463161103fbc5c6d170c28bcb03b13127d", "random3_02.in": "cab5d4d77bbf761ffc61965190205fc079820d08a278ab45e60d66cfd5548690", "random3_02.out": "9eb93a753bf29e7d4b57d5fe88e3b9cf1d30bb1c6ef7b0e3c62267e793f97135", + "random_00.in": "fdf3d70976723693e81019bace27a5694f56725bc95ae5b0a54c63887cc2e3c6", + "random_00.out": "fc5728ed5c7cd451f4aa0ce60ff24688ada311eece10a254c2797f18a023629b", + "random_01.in": "77be302a7b07d1f9c55cb0e43fd502af30ecbe7ee013db0a5a27100387d95542", + "random_01.out": "560440fc1763a2c44a80555370c6b8c01175d5f545704ef2f631892160df0a0f", + "random_02.in": "4d947107466ca1262678bf707a0a7d6cfe3c6feeb412b5e0ae8f54248c22f0fe", + "random_02.out": "b4700d13397e89912b98d47d8de387d4c8dff791aca67251b3a888fb246e54be", "small_00.in": "a55a5fe923e9cfd4b6fc86f4d1fa6524ef58d2e00805f57a3a87a4f2e0195b4a", "small_00.out": "6088af775600493389506c87350d8a8e292826f5c1d1dc19bbb5f7a1065952e6", "small_01.in": "ef075086c922bfe337c0e3fbd4d1d7bd37a4e4854e9092c7bd718c764127595b", @@ -57,4 +57,4 @@ "small_absolute_values_01.out": "a3619c7662b614f3b07cca6ab4d753d591a203a78a04a0cc20dc1b002e77f52e", "small_absolute_values_02.in": "8bf67d5d93dac15a5ad7122be83c2545bf5b86d742e46993cb7b9aeca2f9547d", "small_absolute_values_02.out": "101c7f11f2b4ca4d23c5a04ef4235110fa06eadfe03f79ddcff6638e305c9855" -} +} \ No newline at end of file diff --git a/data_structure/range_chmin_chmax_add_range_sum/sol/correct.cpp b/data_structure/range_chmin_chmax_add_range_sum/sol/correct.cpp index 9bcfa453b..905aad3b5 100644 --- a/data_structure/range_chmin_chmax_add_range_sum/sol/correct.cpp +++ b/data_structure/range_chmin_chmax_add_range_sum/sol/correct.cpp @@ -6,297 +6,264 @@ #include #include -#define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i)) -#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i)) -#define REP_R(i, n) for (int i = (int)(n) - 1; (i) >= 0; -- (i)) -#define REP3R(i, m, n) for (int i = (int)(n) - 1; (i) >= (int)(m); -- (i)) +#define REP(i, n) for (int i = 0; (i) < (int)(n); ++(i)) +#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++(i)) +#define REP_R(i, n) for (int i = (int)(n)-1; (i) >= 0; --(i)) +#define REP3R(i, m, n) for (int i = (int)(n)-1; (i) >= (int)(m); --(i)) #define ALL(x) std::begin(x), std::end(x) /** * @brief a segment tree beats */ class segment_tree_beats { - // MEMO: values for queries (max, min, lazy_add, and lazy_update) already apply to the current node; but not for children - typedef struct { - int64_t max; - int64_t max_second; - int max_count; - int64_t min; - int64_t min_second; - int min_count; - int64_t lazy_add; - int64_t lazy_update; - int64_t sum; - } value_type; + // MEMO: values for queries (max, min, lazy_add, and lazy_update) already apply to the current node; but not for children + typedef struct { + int64_t max; + int64_t max_second; + int max_count; + int64_t min; + int64_t min_second; + int min_count; + int64_t lazy_add; + int64_t lazy_update; + int64_t sum; + } value_type; - int n; - std::vector a; + int n; + std::vector a; public: - segment_tree_beats() = default; - segment_tree_beats(int n_) { - n = 1; while (n < n_) n *= 2; - a.resize(2 * n - 1); - tag(0, 0); - } - template - segment_tree_beats(InputIterator first, InputIterator last) { - int n_ = std::distance(first, last); - n = 1; while (n < n_) n *= 2; - a.resize(2 * n - 1); - REP (i, n_) { - tag(n - 1 + i, *(first + i)); - } - REP3 (i, n_, n) { - tag(n - 1 + i, 0); - } - REP_R (i, n - 1) { - update(i); - } - } + segment_tree_beats() = default; + template + segment_tree_beats(InputIterator first, InputIterator last) { + int n_ = std::distance(first, last); + n = 1; + while (n < n_) n *= 2; + a.resize(2 * n - 1); + REP(i, n_) { tag(n - 1 + i, *(first + i)); } + REP3(i, n_, n) { tag(n - 1 + i, 0); } + REP_R(i, n - 1) { update(i); } + } - void range_chmin(int l, int r, int64_t value) { // 0-based, [l, r) - assert (0 <= l and l <= r and r <= n); - range_apply(0, 0, n, l, r, value); - } - void range_chmax(int l, int r, int64_t value) { // 0-based, [l, r) - assert (0 <= l and l <= r and r <= n); - range_apply(0, 0, n, l, r, value); - } - void range_add(int l, int r, int64_t value) { // 0-based, [l, r) - assert (0 <= l and l <= r and r <= n); - range_apply(0, 0, n, l, r, value); - } - void range_update(int l, int r, int64_t value) { // 0-based, [l, r) - assert (0 <= l and l <= r and r <= n); - range_apply(0, 0, n, l, r, value); - } + void range_chmin(int l, int r, int64_t value) { // 0-based, [l, r) + assert(0 <= l and l <= r and r <= n); + range_apply(0, 0, n, l, r, value); + } + void range_chmax(int l, int r, int64_t value) { // 0-based, [l, r) + assert(0 <= l and l <= r and r <= n); + range_apply(0, 0, n, l, r, value); + } + void range_add(int l, int r, int64_t value) { // 0-based, [l, r) + assert(0 <= l and l <= r and r <= n); + range_apply(0, 0, n, l, r, value); + } + void range_update(int l, int r, int64_t value) { // 0-based, [l, r) + assert(0 <= l and l <= r and r <= n); + range_apply(0, 0, n, l, r, value); + } - int64_t range_min(int l, int r) { // 0-based, [l, r) - assert (0 <= l and l <= r and r <= n); - return range_get(0, 0, n, l, r); - } - int64_t range_max(int l, int r) { // 0-based, [l, r) - assert (0 <= l and l <= r and r <= n); - return range_get(0, 0, n, l, r); - } - int64_t range_sum(int l, int r) { // 0-based, [l, r) - assert (0 <= l and l <= r and r <= n); - return range_get(0, 0, n, l, r); - } + int64_t range_min(int l, int r) { // 0-based, [l, r) + assert(0 <= l and l <= r and r <= n); + return range_get(0, 0, n, l, r); + } + int64_t range_max(int l, int r) { // 0-based, [l, r) + assert(0 <= l and l <= r and r <= n); + return range_get(0, 0, n, l, r); + } + int64_t range_sum(int l, int r) { // 0-based, [l, r) + assert(0 <= l and l <= r and r <= n); + return range_get(0, 0, n, l, r); + } private: - static constexpr char CHMIN = 0; - static constexpr char CHMAX = 1; - static constexpr char ADD = 2; - static constexpr char UPDATE = 3; - static constexpr char MIN = 10; - static constexpr char MAX = 11; - static constexpr char SUM = 12; + static constexpr char CHMIN = 0; + static constexpr char CHMAX = 1; + static constexpr char ADD = 2; + static constexpr char UPDATE = 3; + static constexpr char MIN = 10; + static constexpr char MAX = 11; + static constexpr char SUM = 12; - template - void range_apply(int i, int il, int ir, int l, int r, int64_t g) { - if (ir <= l or r <= il or break_condition(i, g)) { - // break - } else if (l <= il and ir <= r and tag_condition(i, g)) { - tag(i, g); - } else { - pushdown(i); - range_apply(2 * i + 1, il, (il + ir) / 2, l, r, g); - range_apply(2 * i + 2, (il + ir) / 2, ir, l, r, g); - update(i); - } + template + void range_apply(int i, int il, int ir, int l, int r, int64_t g) { + if (ir <= l or r <= il or break_condition(i, g)) { + // break + } else if (l <= il and ir <= r and tag_condition(i, g)) { + tag(i, g); + } else { + pushdown(i); + range_apply(2 * i + 1, il, (il + ir) / 2, l, r, g); + range_apply(2 * i + 2, (il + ir) / 2, ir, l, r, g); + update(i); } - template - inline bool break_condition(int i, int64_t g) { - switch (TYPE) { - case CHMIN: return a[i].max <= g; - case CHMAX: return g <= a[i].min; - case ADD: return false; - case UPDATE: return false; - default: assert (false); - } + } + template + inline bool break_condition(int i, int64_t g) { + switch (TYPE) { + case CHMIN: return a[i].max <= g; + case CHMAX: return g <= a[i].min; + case ADD: return false; + case UPDATE: return false; + default: assert(false); } - template - inline bool tag_condition(int i, int64_t g) { - switch (TYPE) { - case CHMIN: return a[i].max_second < g and g < a[i].max; - case CHMAX: return a[i].min < g and g < a[i].min_second; - case ADD: return true; - case UPDATE: return true; - default: assert (false); - } + } + template + inline bool tag_condition(int i, int64_t g) { + switch (TYPE) { + case CHMIN: return a[i].max_second < g and g < a[i].max; + case CHMAX: return a[i].min < g and g < a[i].min_second; + case ADD: return true; + case UPDATE: return true; + default: assert(false); } - template - inline void tag(int i, int64_t g) { - int length = n >> (32 - __builtin_clz(i + 1) - 1); - if (TYPE == CHMIN) { - if (a[i].max == a[i].min or g <= a[i].min) { - tag(i, g); - return; - } - if (a[i].max != INT64_MIN) { - a[i].sum -= a[i].max * a[i].max_count; - } - a[i].max = g; - a[i].min_second = std::min(a[i].min_second, g); - if (a[i].lazy_update != INT64_MAX) { - a[i].lazy_update = std::min(a[i].lazy_update, g); - } - a[i].sum += g * a[i].max_count; - } else if (TYPE == CHMAX) { - if (a[i].max == a[i].min or a[i].max <= g) { - tag(i, g); - return; - } - if (a[i].min != INT64_MAX) { - a[i].sum -= a[i].min * a[i].min_count; - } - a[i].min = g; - a[i].max_second = std::max(a[i].max_second, g); - if (a[i].lazy_update != INT64_MAX) { - a[i].lazy_update = std::max(a[i].lazy_update, g); - } - a[i].sum += g * a[i].min_count; - } else if (TYPE == ADD) { - if (a[i].max != INT64_MAX) { - a[i].max += g; - } - if (a[i].max_second != INT64_MIN) { - a[i].max_second += g; - } - if (a[i].min != INT64_MIN) { - a[i].min += g; - } - if (a[i].min_second != INT64_MAX) { - a[i].min_second += g; - } - a[i].lazy_add += g; - if (a[i].lazy_update != INT64_MAX) { - a[i].lazy_update += g; - } - a[i].sum += g * length; - } else if (TYPE == UPDATE) { - a[i].max = g; - a[i].max_second = INT64_MIN; - a[i].max_count = length; - a[i].min = g; - a[i].min_second = INT64_MAX; - a[i].min_count = length; - a[i].lazy_add = 0; - a[i].lazy_update = INT64_MAX; - a[i].sum = g * length; - } else { - assert (false); - } + } + template + inline void tag(int i, int64_t g) { + int length = n >> (32 - __builtin_clz(i + 1) - 1); + if (TYPE == CHMIN) { + if (a[i].max == a[i].min or g <= a[i].min) { + tag(i, g); + return; + } + if (a[i].max != INT64_MIN) { a[i].sum -= a[i].max * a[i].max_count; } + a[i].max = g; + a[i].min_second = std::min(a[i].min_second, g); + if (a[i].lazy_update != INT64_MAX) { a[i].lazy_update = std::min(a[i].lazy_update, g); } + a[i].sum += g * a[i].max_count; + } else if (TYPE == CHMAX) { + if (a[i].max == a[i].min or a[i].max <= g) { + tag(i, g); + return; + } + if (a[i].min != INT64_MAX) { a[i].sum -= a[i].min * a[i].min_count; } + a[i].min = g; + a[i].max_second = std::max(a[i].max_second, g); + if (a[i].lazy_update != INT64_MAX) { a[i].lazy_update = std::max(a[i].lazy_update, g); } + a[i].sum += g * a[i].min_count; + } else if (TYPE == ADD) { + if (a[i].max != INT64_MAX) { a[i].max += g; } + if (a[i].max_second != INT64_MIN) { a[i].max_second += g; } + if (a[i].min != INT64_MIN) { a[i].min += g; } + if (a[i].min_second != INT64_MAX) { a[i].min_second += g; } + a[i].lazy_add += g; + if (a[i].lazy_update != INT64_MAX) { a[i].lazy_update += g; } + a[i].sum += g * length; + } else if (TYPE == UPDATE) { + a[i].max = g; + a[i].max_second = INT64_MIN; + a[i].max_count = length; + a[i].min = g; + a[i].min_second = INT64_MAX; + a[i].min_count = length; + a[i].lazy_add = 0; + a[i].lazy_update = INT64_MAX; + a[i].sum = g * length; + } else { + assert(false); } - void pushdown(int i) { - int l = 2 * i + 1; - int r = 2 * i + 2; - // update - if (a[i].lazy_update != INT64_MAX) { - tag(l, a[i].lazy_update); - tag(r, a[i].lazy_update); - a[i].lazy_update = INT64_MAX; - return; - } - // add - if (a[i].lazy_add != 0) { - tag(l, a[i].lazy_add); - tag(r, a[i].lazy_add); - a[i].lazy_add = 0; - } - // chmin - if (a[i].max < a[l].max) { - tag(l, a[i].max); - } - if (a[i].max < a[r].max) { - tag(r, a[i].max); - } - // chmax - if (a[l].min < a[i].min) { - tag(l, a[i].min); - } - if (a[r].min < a[i].min) { - tag(r, a[i].min); - } + } + void pushdown(int i) { + int l = 2 * i + 1; + int r = 2 * i + 2; + // update + if (a[i].lazy_update != INT64_MAX) { + tag(l, a[i].lazy_update); + tag(r, a[i].lazy_update); + a[i].lazy_update = INT64_MAX; + return; } - void update(int i) { - int l = 2 * i + 1; - int r = 2 * i + 2; - // chmin - std::vector b { a[l].max, a[l].max_second, a[r].max, a[r].max_second }; - std::sort(b.rbegin(), b.rend()); - b.erase(std::unique(ALL(b)), b.end()); - a[i].max = b[0]; - a[i].max_second = b[1]; - a[i].max_count = (b[0] == a[l].max ? a[l].max_count : 0) + (b[0] == a[r].max ? a[r].max_count : 0); - // chmax - std::vector c { a[l].min, a[l].min_second, a[r].min, a[r].min_second }; - std::sort(ALL(c)); - c.erase(std::unique(ALL(c)), c.end()); - a[i].min = c[0]; - a[i].min_second = c[1]; - a[i].min_count = (c[0] == a[l].min ? a[l].min_count : 0) + (c[0] == a[r].min ? a[r].min_count : 0); - // add - a[i].lazy_add = 0; - // update - a[i].lazy_update = INT64_MAX; - // sum - a[i].sum = a[l].sum + a[r].sum; + // add + if (a[i].lazy_add != 0) { + tag(l, a[i].lazy_add); + tag(r, a[i].lazy_add); + a[i].lazy_add = 0; } + // chmin + if (a[i].max < a[l].max) { tag(l, a[i].max); } + if (a[i].max < a[r].max) { tag(r, a[i].max); } + // chmax + if (a[l].min < a[i].min) { tag(l, a[i].min); } + if (a[r].min < a[i].min) { tag(r, a[i].min); } + } + void update(int i) { + int l = 2 * i + 1; + int r = 2 * i + 2; + // chmin + std::vector b{a[l].max, a[l].max_second, a[r].max, a[r].max_second}; + std::sort(b.rbegin(), b.rend()); + b.erase(std::unique(ALL(b)), b.end()); + a[i].max = b[0]; + a[i].max_second = b[1]; + a[i].max_count = (b[0] == a[l].max ? a[l].max_count : 0) + (b[0] == a[r].max ? a[r].max_count : 0); + // chmax + std::vector c{a[l].min, a[l].min_second, a[r].min, a[r].min_second}; + std::sort(ALL(c)); + c.erase(std::unique(ALL(c)), c.end()); + a[i].min = c[0]; + a[i].min_second = c[1]; + a[i].min_count = (c[0] == a[l].min ? a[l].min_count : 0) + (c[0] == a[r].min ? a[r].min_count : 0); + // add + a[i].lazy_add = 0; + // update + a[i].lazy_update = INT64_MAX; + // sum + a[i].sum = a[l].sum + a[r].sum; + } - template - int64_t range_get(int i, int il, int ir, int l, int r) { - if (ir <= l or r <= il) { - return 0; - } else if (l <= il and ir <= r) { - // base - switch (TYPE) { - case MIN: return a[i].min; - case MAX: return a[i].max; - case SUM: return a[i].sum; - default: assert (false); - } - } else { - pushdown(i); - int64_t value_l = range_get(2 * i + 1, il, (il + ir) / 2, l, r); - int64_t value_r = range_get(2 * i + 2, (il + ir) / 2, ir, l, r); - // mult - switch (TYPE) { - case MIN: return std::min(value_l, value_r); - case MAX: return std::max(value_l, value_r); - case SUM: return value_l + value_r; - default: assert (false); - } - } + template + int64_t range_get(int i, int il, int ir, int l, int r) { + if (ir <= l or r <= il) { + return 0; + } else if (l <= il and ir <= r) { + // base + switch (TYPE) { + case MIN: return a[i].min; + case MAX: return a[i].max; + case SUM: return a[i].sum; + default: assert(false); + } + } else { + pushdown(i); + int64_t value_l = range_get(2 * i + 1, il, (il + ir) / 2, l, r); + int64_t value_r = range_get(2 * i + 2, (il + ir) / 2, ir, l, r); + // mult + switch (TYPE) { + case MIN: return std::min(value_l, value_r); + case MAX: return std::max(value_l, value_r); + case SUM: return value_l + value_r; + default: assert(false); + } } + } }; int main() { - int n, q; scanf("%d%d", &n, &q); + int n, q; + scanf("%d%d", &n, &q); - std::vector a(n); - for (int i = 0; i < n; i++) { - scanf("%lld", &a[i]); - } - segment_tree_beats beats(ALL(a)); + std::vector a(n); + for (int i = 0; i < n; i++) { scanf("%lld", &a[i]); } + segment_tree_beats beats(ALL(a)); - for (int ph = 0; ph < q; ph++) { - int ty, l, r; scanf("%d%d%d", &ty, &l, &r); - if (ty == 0) { - long long b; scanf("%lld", &b); - beats.range_chmin(l, r, b); - } else if (ty == 1) { - long long b; scanf("%lld", &b); - beats.range_chmax(l, r, b); - } else if (ty == 2) { - long long b; scanf("%lld", &b); - beats.range_add(l, r, b); - } else { - long long sum = beats.range_sum(l, r); - printf("%lld\n", sum); - } + for (int ph = 0; ph < q; ph++) { + int ty, l, r; + scanf("%d%d%d", &ty, &l, &r); + if (ty == 0) { + long long b; + scanf("%lld", &b); + beats.range_chmin(l, r, b); + } else if (ty == 1) { + long long b; + scanf("%lld", &b); + beats.range_chmax(l, r, b); + } else if (ty == 2) { + long long b; + scanf("%lld", &b); + beats.range_add(l, r, b); + } else { + long long sum = beats.range_sum(l, r); + printf("%lld\n", sum); } - return 0; + } + return 0; } From 5c9c93bab512bbedfd7777f91e4cb52ddd5e4269 Mon Sep 17 00:00:00 2001 From: maspypy Date: Mon, 6 Jan 2025 16:27:06 +0900 Subject: [PATCH 2/2] save without formatting --- .../sol/correct.cpp | 492 +++++++++--------- 1 file changed, 260 insertions(+), 232 deletions(-) diff --git a/data_structure/range_chmin_chmax_add_range_sum/sol/correct.cpp b/data_structure/range_chmin_chmax_add_range_sum/sol/correct.cpp index 905aad3b5..37929f499 100644 --- a/data_structure/range_chmin_chmax_add_range_sum/sol/correct.cpp +++ b/data_structure/range_chmin_chmax_add_range_sum/sol/correct.cpp @@ -6,264 +6,292 @@ #include #include -#define REP(i, n) for (int i = 0; (i) < (int)(n); ++(i)) -#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++(i)) -#define REP_R(i, n) for (int i = (int)(n)-1; (i) >= 0; --(i)) -#define REP3R(i, m, n) for (int i = (int)(n)-1; (i) >= (int)(m); --(i)) +#define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i)) +#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i)) +#define REP_R(i, n) for (int i = (int)(n) - 1; (i) >= 0; -- (i)) +#define REP3R(i, m, n) for (int i = (int)(n) - 1; (i) >= (int)(m); -- (i)) #define ALL(x) std::begin(x), std::end(x) /** * @brief a segment tree beats */ class segment_tree_beats { - // MEMO: values for queries (max, min, lazy_add, and lazy_update) already apply to the current node; but not for children - typedef struct { - int64_t max; - int64_t max_second; - int max_count; - int64_t min; - int64_t min_second; - int min_count; - int64_t lazy_add; - int64_t lazy_update; - int64_t sum; - } value_type; + // MEMO: values for queries (max, min, lazy_add, and lazy_update) already apply to the current node; but not for children + typedef struct { + int64_t max; + int64_t max_second; + int max_count; + int64_t min; + int64_t min_second; + int min_count; + int64_t lazy_add; + int64_t lazy_update; + int64_t sum; + } value_type; - int n; - std::vector a; + int n; + std::vector a; public: - segment_tree_beats() = default; - template - segment_tree_beats(InputIterator first, InputIterator last) { - int n_ = std::distance(first, last); - n = 1; - while (n < n_) n *= 2; - a.resize(2 * n - 1); - REP(i, n_) { tag(n - 1 + i, *(first + i)); } - REP3(i, n_, n) { tag(n - 1 + i, 0); } - REP_R(i, n - 1) { update(i); } - } + segment_tree_beats() = default; + template + segment_tree_beats(InputIterator first, InputIterator last) { + int n_ = std::distance(first, last); + n = 1; while (n < n_) n *= 2; + a.resize(2 * n - 1); + REP (i, n_) { + tag(n - 1 + i, *(first + i)); + } + REP3 (i, n_, n) { + tag(n - 1 + i, 0); + } + REP_R (i, n - 1) { + update(i); + } + } - void range_chmin(int l, int r, int64_t value) { // 0-based, [l, r) - assert(0 <= l and l <= r and r <= n); - range_apply(0, 0, n, l, r, value); - } - void range_chmax(int l, int r, int64_t value) { // 0-based, [l, r) - assert(0 <= l and l <= r and r <= n); - range_apply(0, 0, n, l, r, value); - } - void range_add(int l, int r, int64_t value) { // 0-based, [l, r) - assert(0 <= l and l <= r and r <= n); - range_apply(0, 0, n, l, r, value); - } - void range_update(int l, int r, int64_t value) { // 0-based, [l, r) - assert(0 <= l and l <= r and r <= n); - range_apply(0, 0, n, l, r, value); - } + void range_chmin(int l, int r, int64_t value) { // 0-based, [l, r) + assert (0 <= l and l <= r and r <= n); + range_apply(0, 0, n, l, r, value); + } + void range_chmax(int l, int r, int64_t value) { // 0-based, [l, r) + assert (0 <= l and l <= r and r <= n); + range_apply(0, 0, n, l, r, value); + } + void range_add(int l, int r, int64_t value) { // 0-based, [l, r) + assert (0 <= l and l <= r and r <= n); + range_apply(0, 0, n, l, r, value); + } + void range_update(int l, int r, int64_t value) { // 0-based, [l, r) + assert (0 <= l and l <= r and r <= n); + range_apply(0, 0, n, l, r, value); + } - int64_t range_min(int l, int r) { // 0-based, [l, r) - assert(0 <= l and l <= r and r <= n); - return range_get(0, 0, n, l, r); - } - int64_t range_max(int l, int r) { // 0-based, [l, r) - assert(0 <= l and l <= r and r <= n); - return range_get(0, 0, n, l, r); - } - int64_t range_sum(int l, int r) { // 0-based, [l, r) - assert(0 <= l and l <= r and r <= n); - return range_get(0, 0, n, l, r); - } + int64_t range_min(int l, int r) { // 0-based, [l, r) + assert (0 <= l and l <= r and r <= n); + return range_get(0, 0, n, l, r); + } + int64_t range_max(int l, int r) { // 0-based, [l, r) + assert (0 <= l and l <= r and r <= n); + return range_get(0, 0, n, l, r); + } + int64_t range_sum(int l, int r) { // 0-based, [l, r) + assert (0 <= l and l <= r and r <= n); + return range_get(0, 0, n, l, r); + } private: - static constexpr char CHMIN = 0; - static constexpr char CHMAX = 1; - static constexpr char ADD = 2; - static constexpr char UPDATE = 3; - static constexpr char MIN = 10; - static constexpr char MAX = 11; - static constexpr char SUM = 12; + static constexpr char CHMIN = 0; + static constexpr char CHMAX = 1; + static constexpr char ADD = 2; + static constexpr char UPDATE = 3; + static constexpr char MIN = 10; + static constexpr char MAX = 11; + static constexpr char SUM = 12; - template - void range_apply(int i, int il, int ir, int l, int r, int64_t g) { - if (ir <= l or r <= il or break_condition(i, g)) { - // break - } else if (l <= il and ir <= r and tag_condition(i, g)) { - tag(i, g); - } else { - pushdown(i); - range_apply(2 * i + 1, il, (il + ir) / 2, l, r, g); - range_apply(2 * i + 2, (il + ir) / 2, ir, l, r, g); - update(i); + template + void range_apply(int i, int il, int ir, int l, int r, int64_t g) { + if (ir <= l or r <= il or break_condition(i, g)) { + // break + } else if (l <= il and ir <= r and tag_condition(i, g)) { + tag(i, g); + } else { + pushdown(i); + range_apply(2 * i + 1, il, (il + ir) / 2, l, r, g); + range_apply(2 * i + 2, (il + ir) / 2, ir, l, r, g); + update(i); + } } - } - template - inline bool break_condition(int i, int64_t g) { - switch (TYPE) { - case CHMIN: return a[i].max <= g; - case CHMAX: return g <= a[i].min; - case ADD: return false; - case UPDATE: return false; - default: assert(false); + template + inline bool break_condition(int i, int64_t g) { + switch (TYPE) { + case CHMIN: return a[i].max <= g; + case CHMAX: return g <= a[i].min; + case ADD: return false; + case UPDATE: return false; + default: assert (false); + } } - } - template - inline bool tag_condition(int i, int64_t g) { - switch (TYPE) { - case CHMIN: return a[i].max_second < g and g < a[i].max; - case CHMAX: return a[i].min < g and g < a[i].min_second; - case ADD: return true; - case UPDATE: return true; - default: assert(false); + template + inline bool tag_condition(int i, int64_t g) { + switch (TYPE) { + case CHMIN: return a[i].max_second < g and g < a[i].max; + case CHMAX: return a[i].min < g and g < a[i].min_second; + case ADD: return true; + case UPDATE: return true; + default: assert (false); + } } - } - template - inline void tag(int i, int64_t g) { - int length = n >> (32 - __builtin_clz(i + 1) - 1); - if (TYPE == CHMIN) { - if (a[i].max == a[i].min or g <= a[i].min) { - tag(i, g); - return; - } - if (a[i].max != INT64_MIN) { a[i].sum -= a[i].max * a[i].max_count; } - a[i].max = g; - a[i].min_second = std::min(a[i].min_second, g); - if (a[i].lazy_update != INT64_MAX) { a[i].lazy_update = std::min(a[i].lazy_update, g); } - a[i].sum += g * a[i].max_count; - } else if (TYPE == CHMAX) { - if (a[i].max == a[i].min or a[i].max <= g) { - tag(i, g); - return; - } - if (a[i].min != INT64_MAX) { a[i].sum -= a[i].min * a[i].min_count; } - a[i].min = g; - a[i].max_second = std::max(a[i].max_second, g); - if (a[i].lazy_update != INT64_MAX) { a[i].lazy_update = std::max(a[i].lazy_update, g); } - a[i].sum += g * a[i].min_count; - } else if (TYPE == ADD) { - if (a[i].max != INT64_MAX) { a[i].max += g; } - if (a[i].max_second != INT64_MIN) { a[i].max_second += g; } - if (a[i].min != INT64_MIN) { a[i].min += g; } - if (a[i].min_second != INT64_MAX) { a[i].min_second += g; } - a[i].lazy_add += g; - if (a[i].lazy_update != INT64_MAX) { a[i].lazy_update += g; } - a[i].sum += g * length; - } else if (TYPE == UPDATE) { - a[i].max = g; - a[i].max_second = INT64_MIN; - a[i].max_count = length; - a[i].min = g; - a[i].min_second = INT64_MAX; - a[i].min_count = length; - a[i].lazy_add = 0; - a[i].lazy_update = INT64_MAX; - a[i].sum = g * length; - } else { - assert(false); + template + inline void tag(int i, int64_t g) { + int length = n >> (32 - __builtin_clz(i + 1) - 1); + if (TYPE == CHMIN) { + if (a[i].max == a[i].min or g <= a[i].min) { + tag(i, g); + return; + } + if (a[i].max != INT64_MIN) { + a[i].sum -= a[i].max * a[i].max_count; + } + a[i].max = g; + a[i].min_second = std::min(a[i].min_second, g); + if (a[i].lazy_update != INT64_MAX) { + a[i].lazy_update = std::min(a[i].lazy_update, g); + } + a[i].sum += g * a[i].max_count; + } else if (TYPE == CHMAX) { + if (a[i].max == a[i].min or a[i].max <= g) { + tag(i, g); + return; + } + if (a[i].min != INT64_MAX) { + a[i].sum -= a[i].min * a[i].min_count; + } + a[i].min = g; + a[i].max_second = std::max(a[i].max_second, g); + if (a[i].lazy_update != INT64_MAX) { + a[i].lazy_update = std::max(a[i].lazy_update, g); + } + a[i].sum += g * a[i].min_count; + } else if (TYPE == ADD) { + if (a[i].max != INT64_MAX) { + a[i].max += g; + } + if (a[i].max_second != INT64_MIN) { + a[i].max_second += g; + } + if (a[i].min != INT64_MIN) { + a[i].min += g; + } + if (a[i].min_second != INT64_MAX) { + a[i].min_second += g; + } + a[i].lazy_add += g; + if (a[i].lazy_update != INT64_MAX) { + a[i].lazy_update += g; + } + a[i].sum += g * length; + } else if (TYPE == UPDATE) { + a[i].max = g; + a[i].max_second = INT64_MIN; + a[i].max_count = length; + a[i].min = g; + a[i].min_second = INT64_MAX; + a[i].min_count = length; + a[i].lazy_add = 0; + a[i].lazy_update = INT64_MAX; + a[i].sum = g * length; + } else { + assert (false); + } } - } - void pushdown(int i) { - int l = 2 * i + 1; - int r = 2 * i + 2; - // update - if (a[i].lazy_update != INT64_MAX) { - tag(l, a[i].lazy_update); - tag(r, a[i].lazy_update); - a[i].lazy_update = INT64_MAX; - return; + void pushdown(int i) { + int l = 2 * i + 1; + int r = 2 * i + 2; + // update + if (a[i].lazy_update != INT64_MAX) { + tag(l, a[i].lazy_update); + tag(r, a[i].lazy_update); + a[i].lazy_update = INT64_MAX; + return; + } + // add + if (a[i].lazy_add != 0) { + tag(l, a[i].lazy_add); + tag(r, a[i].lazy_add); + a[i].lazy_add = 0; + } + // chmin + if (a[i].max < a[l].max) { + tag(l, a[i].max); + } + if (a[i].max < a[r].max) { + tag(r, a[i].max); + } + // chmax + if (a[l].min < a[i].min) { + tag(l, a[i].min); + } + if (a[r].min < a[i].min) { + tag(r, a[i].min); + } } - // add - if (a[i].lazy_add != 0) { - tag(l, a[i].lazy_add); - tag(r, a[i].lazy_add); - a[i].lazy_add = 0; + void update(int i) { + int l = 2 * i + 1; + int r = 2 * i + 2; + // chmin + std::vector b { a[l].max, a[l].max_second, a[r].max, a[r].max_second }; + std::sort(b.rbegin(), b.rend()); + b.erase(std::unique(ALL(b)), b.end()); + a[i].max = b[0]; + a[i].max_second = b[1]; + a[i].max_count = (b[0] == a[l].max ? a[l].max_count : 0) + (b[0] == a[r].max ? a[r].max_count : 0); + // chmax + std::vector c { a[l].min, a[l].min_second, a[r].min, a[r].min_second }; + std::sort(ALL(c)); + c.erase(std::unique(ALL(c)), c.end()); + a[i].min = c[0]; + a[i].min_second = c[1]; + a[i].min_count = (c[0] == a[l].min ? a[l].min_count : 0) + (c[0] == a[r].min ? a[r].min_count : 0); + // add + a[i].lazy_add = 0; + // update + a[i].lazy_update = INT64_MAX; + // sum + a[i].sum = a[l].sum + a[r].sum; } - // chmin - if (a[i].max < a[l].max) { tag(l, a[i].max); } - if (a[i].max < a[r].max) { tag(r, a[i].max); } - // chmax - if (a[l].min < a[i].min) { tag(l, a[i].min); } - if (a[r].min < a[i].min) { tag(r, a[i].min); } - } - void update(int i) { - int l = 2 * i + 1; - int r = 2 * i + 2; - // chmin - std::vector b{a[l].max, a[l].max_second, a[r].max, a[r].max_second}; - std::sort(b.rbegin(), b.rend()); - b.erase(std::unique(ALL(b)), b.end()); - a[i].max = b[0]; - a[i].max_second = b[1]; - a[i].max_count = (b[0] == a[l].max ? a[l].max_count : 0) + (b[0] == a[r].max ? a[r].max_count : 0); - // chmax - std::vector c{a[l].min, a[l].min_second, a[r].min, a[r].min_second}; - std::sort(ALL(c)); - c.erase(std::unique(ALL(c)), c.end()); - a[i].min = c[0]; - a[i].min_second = c[1]; - a[i].min_count = (c[0] == a[l].min ? a[l].min_count : 0) + (c[0] == a[r].min ? a[r].min_count : 0); - // add - a[i].lazy_add = 0; - // update - a[i].lazy_update = INT64_MAX; - // sum - a[i].sum = a[l].sum + a[r].sum; - } - template - int64_t range_get(int i, int il, int ir, int l, int r) { - if (ir <= l or r <= il) { - return 0; - } else if (l <= il and ir <= r) { - // base - switch (TYPE) { - case MIN: return a[i].min; - case MAX: return a[i].max; - case SUM: return a[i].sum; - default: assert(false); - } - } else { - pushdown(i); - int64_t value_l = range_get(2 * i + 1, il, (il + ir) / 2, l, r); - int64_t value_r = range_get(2 * i + 2, (il + ir) / 2, ir, l, r); - // mult - switch (TYPE) { - case MIN: return std::min(value_l, value_r); - case MAX: return std::max(value_l, value_r); - case SUM: return value_l + value_r; - default: assert(false); - } + template + int64_t range_get(int i, int il, int ir, int l, int r) { + if (ir <= l or r <= il) { + return 0; + } else if (l <= il and ir <= r) { + // base + switch (TYPE) { + case MIN: return a[i].min; + case MAX: return a[i].max; + case SUM: return a[i].sum; + default: assert (false); + } + } else { + pushdown(i); + int64_t value_l = range_get(2 * i + 1, il, (il + ir) / 2, l, r); + int64_t value_r = range_get(2 * i + 2, (il + ir) / 2, ir, l, r); + // mult + switch (TYPE) { + case MIN: return std::min(value_l, value_r); + case MAX: return std::max(value_l, value_r); + case SUM: return value_l + value_r; + default: assert (false); + } + } } - } }; int main() { - int n, q; - scanf("%d%d", &n, &q); + int n, q; scanf("%d%d", &n, &q); - std::vector a(n); - for (int i = 0; i < n; i++) { scanf("%lld", &a[i]); } - segment_tree_beats beats(ALL(a)); + std::vector a(n); + for (int i = 0; i < n; i++) { + scanf("%lld", &a[i]); + } + segment_tree_beats beats(ALL(a)); - for (int ph = 0; ph < q; ph++) { - int ty, l, r; - scanf("%d%d%d", &ty, &l, &r); - if (ty == 0) { - long long b; - scanf("%lld", &b); - beats.range_chmin(l, r, b); - } else if (ty == 1) { - long long b; - scanf("%lld", &b); - beats.range_chmax(l, r, b); - } else if (ty == 2) { - long long b; - scanf("%lld", &b); - beats.range_add(l, r, b); - } else { - long long sum = beats.range_sum(l, r); - printf("%lld\n", sum); + for (int ph = 0; ph < q; ph++) { + int ty, l, r; scanf("%d%d%d", &ty, &l, &r); + if (ty == 0) { + long long b; scanf("%lld", &b); + beats.range_chmin(l, r, b); + } else if (ty == 1) { + long long b; scanf("%lld", &b); + beats.range_chmax(l, r, b); + } else if (ty == 2) { + long long b; scanf("%lld", &b); + beats.range_add(l, r, b); + } else { + long long sum = beats.range_sum(l, r); + printf("%lld\n", sum); + } } - } - return 0; + return 0; }