diff --git a/data_structure/range_affine_range_sum_large_array/checker.cpp b/data_structure/range_affine_range_sum_large_array/checker.cpp new file mode 100644 index 000000000..6a66d5330 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/checker.cpp @@ -0,0 +1,62 @@ +// https://github.com/MikeMirzayanov/testlib/blob/master/checkers/wcmp.cpp + +// The MIT License (MIT) + +// Copyright (c) 2015 Mike Mirzayanov + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "testlib.h" + +using namespace std; + +int main(int argc, char * argv[]) +{ + setName("compare sequences of tokens"); + registerTestlibCmd(argc, argv); + + int n = 0; + string j, p; + + while (!ans.seekEof() && !ouf.seekEof()) + { + n++; + + ans.readWordTo(j); + ouf.readWordTo(p); + + if (j != p) + quitf(_wa, "%d%s words differ - expected: '%s', found: '%s'", n, englishEnding(n).c_str(), compress(j).c_str(), compress(p).c_str()); + } + + if (ans.seekEof() && ouf.seekEof()) + { + if (n == 1) + quitf(_ok, "\"%s\"", compress(j).c_str()); + else + quitf(_ok, "%d tokens", n); + } + else + { + if (ans.seekEof()) + quitf(_wa, "Participant output contains extra tokens"); + else + quitf(_wa, "Unexpected EOF in the participants output"); + } +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/dense.cpp b/data_structure/range_affine_range_sum_large_array/gen/dense.cpp new file mode 100644 index 000000000..3748255a4 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/dense.cpp @@ -0,0 +1,43 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int q = Q_MAX; + printf("%d %d\n", n, q); + + int ws[] = {1, 1000, 500000}; + int w = ws[seed % 3]; + + int L = gen.uniform(0, n - w); + int R = L + w; + + auto idx = [&]() -> int { return gen.uniform(L, R - 1); }; + + auto idx2 = [&]() -> pair { + int a = idx(), b = idx(); + if (a > b) swap(a, b); + ++b; + return {a, b}; + }; + + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + auto p = idx2(); + + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/example_00.in b/data_structure/range_affine_range_sum_large_array/gen/example_00.in new file mode 100644 index 000000000..deec09a9c --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/example_00.in @@ -0,0 +1,7 @@ +1000000000 6 +0 0 100 10 1 +1 10 90 +1 0 1000000000 +0 50 10000 10 1 +1 10 90 +1 0 1000000000 diff --git a/data_structure/range_affine_range_sum_large_array/gen/many_query_0.cpp b/data_structure/range_affine_range_sum_large_array/gen/many_query_0.cpp new file mode 100644 index 000000000..3268b16e3 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/many_query_0.cpp @@ -0,0 +1,27 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int q = Q_MAX; + printf("%d %d\n", n, q); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 100); + t = (t == 0 ? 1 : 0); + auto p = gen.uniform_pair(0, n); + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/many_query_1.cpp b/data_structure/range_affine_range_sum_large_array/gen/many_query_1.cpp new file mode 100644 index 000000000..cc3a8ede2 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/many_query_1.cpp @@ -0,0 +1,27 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int q = Q_MAX; + printf("%d %d\n", n, q); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 100); + t = (t == 0 ? 0 : 1); + auto p = gen.uniform_pair(0, n); + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/max_random.cpp b/data_structure/range_affine_range_sum_large_array/gen/max_random.cpp new file mode 100644 index 000000000..b7aa9d3ce --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/max_random.cpp @@ -0,0 +1,26 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int q = Q_MAX; + printf("%d %d\n", n, q); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + auto p = gen.uniform_pair(0, n); + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/near_0_and_N.cpp b/data_structure/range_affine_range_sum_large_array/gen/near_0_and_N.cpp new file mode 100644 index 000000000..4fa3cc734 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/near_0_and_N.cpp @@ -0,0 +1,42 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int q = Q_MAX; + printf("%d %d\n", n, q); + + auto idx = [&]() -> int { + int t = gen.uniform(0, 2); + if (t == 0) return gen.uniform(0, n - 1); + if (t == 1) return gen.uniform(0, 1000); + if (t == 2) return gen.uniform(n - 1000, n - 1); + return 0; + }; + + auto idx2 = [&]() -> pair { + int a = idx(), b = idx(); + if (a > b) swap(a, b); + ++b; + return {a, b}; + }; + + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + auto p = idx2(); + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/query_0_then_1.cpp b/data_structure/range_affine_range_sum_large_array/gen/query_0_then_1.cpp new file mode 100644 index 000000000..041794bf3 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/query_0_then_1.cpp @@ -0,0 +1,27 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int q = Q_MAX; + printf("%d %d\n", n, q); + for (int i = 0; i < q; i++) { + int t = (i < q / 2 ? 0 : 1); + if (gen.uniform(0, 100) == 0) t = 1 - t; + auto p = gen.uniform_pair(0, n); + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/random.cpp b/data_structure/range_affine_range_sum_large_array/gen/random.cpp new file mode 100644 index 000000000..cc573764f --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/random.cpp @@ -0,0 +1,26 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = gen.uniform(1LL, N_MAX); + int q = gen.uniform(1LL, Q_MAX); + printf("%d %d\n", n, q); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + auto p = gen.uniform_pair(0, n); + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/small_N.cpp b/data_structure/range_affine_range_sum_large_array/gen/small_N.cpp new file mode 100644 index 000000000..895ca8d3e --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/small_N.cpp @@ -0,0 +1,26 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = seed + 1; + int q = Q_MAX; + printf("%d %d\n", n, q); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + auto p = gen.uniform_pair(0, n); + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/gen/small_Q.cpp b/data_structure/range_affine_range_sum_large_array/gen/small_Q.cpp new file mode 100644 index 000000000..26cdc7f09 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/gen/small_Q.cpp @@ -0,0 +1,34 @@ +#include "random.h" +#include +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_MAX; + int q; + vector ts; + if (seed == 0) { q = 1, ts = {0}; } + if (seed == 1) { q = 1, ts = {1}; } + if (seed == 2) { q = 2, ts = {0, 0}; } + if (seed == 3) { q = 2, ts = {0, 1}; } + if (seed == 4) { q = 2, ts = {1, 0}; } + if (seed == 5) { q = 2, ts = {1, 1}; } + + printf("%d %d\n", n, q); + for (int i = 0; i < q; i++) { + int t = ts[i]; + auto p = gen.uniform_pair(0, n); + if (t == 0) { + int b = gen.uniform(1LL, MOD - 1); + int c = gen.uniform(0LL, MOD - 1); + printf("%d %d %d %d %d\n", t, p.first, p.second, b, c); + } else { + printf("%d %d %d\n", t, p.first, p.second); + } + } + return 0; +} diff --git a/data_structure/range_affine_range_sum_large_array/hash.json b/data_structure/range_affine_range_sum_large_array/hash.json new file mode 100644 index 000000000..ac6b64a83 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/hash.json @@ -0,0 +1,64 @@ +{ + "dense_00.in": "7ad4bfd182ae8044a7e815e4c6f443a3edaca157c187a8f2c0ec6118d7967355", + "dense_00.out": "eace4e29eaeaf09d459f7654b6ba26208fe8ab720606b8db653c338a612a2f5d", + "dense_01.in": "78f0ecf6674b6f7e0997f8e858f055c625c3830aebd03f03d3218bc017183f3b", + "dense_01.out": "54742a91271fcf5ca857d9dc87fec87aa9cd92172108eeefef438ba877f1a59f", + "dense_02.in": "1ca6d2dd9ac951fbbefc2ee3bedcdfe352a1ce80a8ca13f882c88619e43e3588", + "dense_02.out": "39bc004254ee88ae9a9603daf107e3483ebb5bae6efeb5fcfd0c90c0268f366a", + "example_00.in": "faa5ffc54ec68e5f871d58118c938872bf4b10c6bc7450c6a59dc0aa0726a200", + "example_00.out": "c99f9367c3f9cc3211c9fe27dff3f647a956974c55f7f373f29443f785cfa71e", + "many_query_0_00.in": "b5216e64b7145c8c365da1b4c2bbb9094d5dacab76861f9b717d392bd7132127", + "many_query_0_00.out": "4c4e49d298506348871fe358559dad90504ab4c6c9a5f832a63ba992acadb2af", + "many_query_0_01.in": "fa596f3c37e5daee2a799fc34c10afe5b3e94b852eff20afbe060934d21347a0", + "many_query_0_01.out": "c99c20c28388fbdf4ffd5332564b1728a157e2c4768ce82e173764c52fe0859b", + "many_query_1_00.in": "9098488f9e3c4d0eaa1d593d8b8db71758af12ed958c68ad1ba8e7276d0bed05", + "many_query_1_00.out": "e1a70d63a5a9e5f280c0e9a1f81dd6eb8b9d0ee6204d3b66dd295e9d33cfabb4", + "many_query_1_01.in": "f7814e01f8bca17a7f6f812849665ac5e64040e5f354666c52e623ef997b376c", + "many_query_1_01.out": "b614add64b7995849ff4d3139b49cbb1430bd59adff4aa2c7884320b55661097", + "max_random_00.in": "d97eca08977779200ffbc73e9dc0411e7e7f02c6de9cee25c32973d3665809d7", + "max_random_00.out": "eafa2864aaa6ad9b5c9737b05aa9b34ccd1198d4e7bea9caca8e359cadeb92ad", + "max_random_01.in": "d06b03d0d018d00cde1c72028f737d9886f69853bb5c52d585647bfe465d0940", + "max_random_01.out": "16757a5c262057f1d8a8437060ea350f6571cadd6577040152ee84f3b35e5063", + "max_random_02.in": "197c677764437651fbb83f7273a55c1a70816309dc66aa7a8cacf80b39508114", + "max_random_02.out": "1fbcb34024c46b51b9d4752b30f6f9ccac28f95d7902b5f8d3d89e1b5accbf53", + "near_0_and_N_00.in": "b5e6d733488842e0ac95245ddfbaf09624f87f1955b71dd08e33caa955a57f1c", + "near_0_and_N_00.out": "198384983e71f15507236e64f2bd9338dd00546f2fc3d5348139c07f709540f0", + "near_0_and_N_01.in": "dfdebd0a877afdf9d1f97d0213c29edb075e4fb6af65d868eb1222993ae25df2", + "near_0_and_N_01.out": "4fe7aed59074124d367cb0b6aa64f58f1cda45df7f909c3cb8f70f5a4ef9260d", + "query_0_then_1_00.in": "bc05f883074fc25e8c3c7ee6740fd711d089ad60dcacc5731f74bed42bf88d51", + "query_0_then_1_00.out": "4e6991c7cd9b400be22a73cc83ae958c48e14da4f300e563ed1bb1fa672d0246", + "query_0_then_1_01.in": "edf40f3624b5bbd7e9d038c06d7999eb631163e4182230c877259ba7d656fbad", + "query_0_then_1_01.out": "1296cc7a91d966e42cf60736fc427e86b412571fff28d9f4193a10686f4d0849", + "random_00.in": "7c3e4f794cea2d9b574331d9a73df4e7619bfb1bb5e0dbf0059cf20d6394516b", + "random_00.out": "69766231bfec5a1b30fc3bc56ecf2a6e37afdae9d05f09d9501eb0dc47ac376d", + "random_01.in": "30c52ae85628583f447ce4473a79d8e0ac5c3976157177ae764935475a7a727c", + "random_01.out": "ecb526939276b947debca9ba098ed88ee2b927415c79eb03c2fb110b1ea187ba", + "random_02.in": "455bfcd30b72ce6a56952779875b56b33172786cd3905dc76305cec3c6bc696a", + "random_02.out": "206b78106174ca38ced3b64db0b819082f0adaeed4299ce95f7481a580bb403c", + "random_03.in": "aa196c4d14d08290b87937eefe7653f33a8af3ba6fb18b7f0b0aa07392939fd0", + "random_03.out": "95d8e5ef2e77e2c02c3cfc24b088338dc35086d0464a256d1986e5c1cdbd740e", + "random_04.in": "6fbc03383f8b40195f2c7e3476c282ca95fbede0d70f2964456dbc330c232aa2", + "random_04.out": "78a96db442c8c13c79f43ecc4f0d8aabb1526e623603a0a64b0b33b69b196e18", + "small_N_00.in": "39dbb23cfa6444430994d5f9fde8937bd8e535fde627a58cac633ac87bd85912", + "small_N_00.out": "ae95ecccf912868201c6ed417cb98024fae9a5e30a2caa4706cfcd04776bfa41", + "small_N_01.in": "969fe88cd60675f83740475d972b26c9f81e9e5ca4c4cd579b40774e55aa7b16", + "small_N_01.out": "97f380e4cbdfa026927154bebafad63673bfeabbddc1121117eb4ce14b4b4130", + "small_N_02.in": "f798db44e58b2451ddf6356df6215f8786929ce3504733c808a7da3ca71ba76c", + "small_N_02.out": "8f4e05e67f71910f559f328785ae0c8ab446a57fe1642e9ed4dbf645f6347c04", + "small_N_03.in": "728a310d3eebe791fd14f20f1e82c9b1752ac283314ec9b442e77e5f7d6d264d", + "small_N_03.out": "c748d0d6b7be8c54b1a9032b92ff2c0a2a92b52f0273c8c883f5379734d6370f", + "small_N_04.in": "8cad110e923744ac91d6843f57430d3a0a865c8186aacf533e819d82ba535388", + "small_N_04.out": "f1847d2a096b8c89cd4ec35d5e47cc6044ef2721b8c488e4fdb95b3c4670ab46", + "small_Q_00.in": "1beea65e9c41ef60df018359c1c6c199a60bb029f7f0d98d2bb118efdbcb11bd", + "small_Q_00.out": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "small_Q_01.in": "7c5d16beb04c5462ffdcbeba6ea75844e6b4cc1239d0c3fd81bcc70daaee9154", + "small_Q_01.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa", + "small_Q_02.in": "1da8a59b212c5b354a07488c6ac099902fc759027054666e7d2c1d1303adbee4", + "small_Q_02.out": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "small_Q_03.in": "a990c2ad0127a1165422d0c6c9b41a5c6acd67050b847ffefbb2b8e33b4aeb27", + "small_Q_03.out": "56ec4345b204ff81beabe839fc3ab459086307010bd9586bc037ed5e0bf07865", + "small_Q_04.in": "06a34a1a99f48ad79cd1e02d2037dc123c2519eeebeaf17d3a5bcfc96228d0fd", + "small_Q_04.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa", + "small_Q_05.in": "34432678add53cceec8e1690a2f56714392b0c85d43cbd725254a6ec6173a2ec", + "small_Q_05.out": "52f96c26a39ed25108a6db43d6e11c6051eba8a498a5baab1891adfa7ac7c262" +} \ No newline at end of file diff --git a/data_structure/range_affine_range_sum_large_array/info.toml b/data_structure/range_affine_range_sum_large_array/info.toml new file mode 100644 index 000000000..1d28db5ed --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/info.toml @@ -0,0 +1,49 @@ +title = 'Range Affine Range Sum (Large Array)' +timelimit = 10.0 +forum = "https://github.com/yosupo06/library-checker-problems/issues/828" +[[tests]] + name = "example.in" + number = 1 + +[[tests]] + name = "random.cpp" + number = 5 + +[[tests]] + name = "small_N.cpp" + number = 5 + +[[tests]] + name = "small_Q.cpp" + number = 6 + +[[tests]] + name = "max_random.cpp" + number = 3 + +[[tests]] + name = "many_query_0.cpp" + number = 2 + +[[tests]] + name = "many_query_1.cpp" + number = 2 + +[[tests]] + name = "query_0_then_1.cpp" + number = 2 + +[[tests]] + name = "near_0_and_N.cpp" + number = 2 + +[[tests]] + name = "dense.cpp" + number = 3 + + + +[params] + N_MAX = 1_000_000_000 + Q_MAX = 100_000 + MOD = 998244353 diff --git a/data_structure/range_affine_range_sum_large_array/sol/correct.cpp b/data_structure/range_affine_range_sum_large_array/sol/correct.cpp new file mode 100644 index 000000000..35938d210 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/sol/correct.cpp @@ -0,0 +1,429 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +using ll = long long; +using u8 = uint8_t; +using u16 = uint16_t; +using u32 = uint32_t; +using u64 = uint64_t; + +template +using vc = vector; + +#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_) +#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i) +#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i) +#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c)) +#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i) +#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i) +#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i) +#define overload4(a, b, c, d, e, ...) e +#define overload3(a, b, c, d, ...) d +#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__) +#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__) + +#define all(x) x.begin(), x.end() +#define len(x) ll(x.size()) +#define elif else if + +#define eb emplace_back +#define mp make_pair +#define mt make_tuple +#define fi first +#define se second + +template +inline bool chmax(T &a, const S &b) { + return (a < b ? a = b, 1 : 0); +} +template +inline bool chmin(T &a, const S &b) { + return (a > b ? a = b, 1 : 0); +} + +// Q*2logN 程度必要 + +// Q*4logN 程度必要? apply で 4logN ノード作っていると思う +template +struct Dynamic_Lazy_SegTree { + using AM = ActedMonoid; + using MX = typename AM::Monoid_X; + using MA = typename AM::Monoid_A; + using X = typename AM::X; + using A = typename AM::A; + using F = function; + F default_prod; + + struct Node { + Node *l, *r; + X x; + A lazy; + }; + + const int NODES; + const ll L0, R0; + Node *pool; + int pid; + using np = Node *; + + Dynamic_Lazy_SegTree( + int NODES, ll L0, ll R0, F default_prod = [](ll, ll) -> X { return MX::unit(); }) + : default_prod(default_prod), NODES(NODES), L0(L0), R0(R0), pid(0) { + pool = new Node[NODES]; + } + ~Dynamic_Lazy_SegTree() { delete[] pool; } + + np new_root() { return new_node(L0, R0); } + + np new_node(const X x) { + assert(pid < NODES); + pool[pid].l = pool[pid].r = nullptr; + pool[pid].x = x; + pool[pid].lazy = MA::unit(); + return &(pool[pid++]); + } + + np new_node(ll l, ll r) { + assert(l < r); + return new_node(default_prod(l, r)); + } + np new_node() { return new_node(L0, R0); } + + np new_node(const vc &dat) { + assert(L0 == 0 && R0 == len(dat)); + auto dfs = [&](auto &dfs, ll l, ll r) -> Node * { + if (l == r) return nullptr; + if (r == l + 1) return new_node(dat[l]); + ll m = (l + r) / 2; + np l_root = dfs(dfs, l, m), r_root = dfs(dfs, m, r); + X x = MX::op(l_root->x, r_root->x); + np root = new_node(x); + root->l = l_root, root->r = r_root; + return root; + }; + return dfs(dfs, 0, len(dat)); + } + + X prod(np root, ll l, ll r) { + if (l == r || !root) return MX::unit(); + assert(pid && L0 <= l && l < r && r <= R0); + X x = MX::unit(); + prod_rec(root, L0, R0, l, r, x, MA::unit()); + return x; + } + + X prod_all(np root) { return prod(root, L0, R0); } + + np set(np root, ll i, const X &x) { + assert(pid && L0 <= i && i < R0); + return set_rec(root, L0, R0, i, x); + } + + np multiply(np root, ll i, const X &x) { + assert(pid && L0 <= i && i < R0); + return multiply_rec(root, L0, R0, i, x); + } + + np apply(np root, ll l, ll r, const A &a) { + if (l == r) return root; + assert(pid && L0 <= l && l < r && r <= R0); + return apply_rec(root, L0, R0, l, r, a); + } + + template + ll max_right(np root, F check, ll L) { + assert(pid && L0 <= L && L <= R0 && check(MX::unit())); + X x = MX::unit(); + return max_right_rec(root, check, L0, R0, L, x); + } + + template + ll min_left(np root, F check, ll R) { + assert(pid && L0 <= R && R <= R0 && check(MX::unit())); + X x = MX::unit(); + return min_left_rec(root, check, L0, R0, R, x); + } + + // f(idx, val) + template + void enumerate(np root, F f) { + auto dfs = [&](auto &dfs, np c, ll l, ll r, A a) -> void { + if (!c) return; + if (r - l == 1) { + f(l, AM::act(c->x, a, 1)); + return; + } + ll m = (l + r) / 2; + a = MA::op(c->lazy, a); + dfs(dfs, c->l, l, m, a); + dfs(dfs, c->r, m, r, a); + }; + dfs(dfs, root, L0, R0, MA::unit()); + } + + void reset() { pid = 0; } + + // root[l:r) を apply(other[l:r),a) で上書きしたものを返す + np copy_interval(np root, np other, ll l, ll r, A a) { + if (root == other) return root; + root = copy_node(root); + copy_interval_rec(root, other, L0, R0, l, r, a); + return root; + } + +private: + np copy_node(np c) { + if (!c || !PERSISTENT) return c; + pool[pid].l = c->l, pool[pid].r = c->r; + pool[pid].x = c->x; + pool[pid].lazy = c->lazy; + return &(pool[pid++]); + } + + void prop(np c, ll l, ll r) { + assert(r - l >= 2); + ll m = (l + r) / 2; + if (c->lazy == MA::unit()) return; + c->l = (c->l ? copy_node(c->l) : new_node(l, m)); + c->l->x = AM::act(c->l->x, c->lazy, m - l); + c->l->lazy = MA::op(c->l->lazy, c->lazy); + c->r = (c->r ? copy_node(c->r) : new_node(m, r)); + c->r->x = AM::act(c->r->x, c->lazy, r - m); + c->r->lazy = MA::op(c->r->lazy, c->lazy); + c->lazy = MA::unit(); + } + + void copy_interval_rec(np c, np d, ll l, ll r, ll ql, ll qr, A a) { + // c[ql,qr) <- apply(d[ql,qr),a) + // もう c は新しくしてある + assert(c); + chmax(ql, l), chmin(qr, r); + if (ql >= qr) return; + if (l == ql && r == qr) { + if (d) { + c->x = AM::act(d->x, a, r - l), c->lazy = MA::op(d->lazy, a); + c->l = d->l, c->r = d->r; + } else { + c->x = AM::act(default_prod(l, r), a, r - l), c->lazy = a; + c->l = nullptr, c->r = nullptr; + } + return; + } + // push + ll m = (l + r) / 2; + c->l = (c->l ? copy_node(c->l) : new_node()); + c->r = (c->r ? copy_node(c->r) : new_node()); + c->l->x = AM::act(c->l->x, c->lazy, m - l); + c->l->lazy = MA::op(c->l->lazy, c->lazy); + c->r->x = AM::act(c->r->x, c->lazy, r - m); + c->r->lazy = MA::op(c->r->lazy, c->lazy); + c->lazy = MA::unit(); + if (d) a = MA::op(d->lazy, a); + copy_interval_rec(c->l, (d && d->l ? d->l : nullptr), l, m, ql, qr, a); + copy_interval_rec(c->r, (d && d->r ? d->r : nullptr), m, r, ql, qr, a); + c->x = MX::op(c->l->x, c->r->x); + return; + } + + np set_rec(np c, ll l, ll r, ll i, const X &x) { + if (r == l + 1) { + c = copy_node(c); + c->x = x; + c->lazy = MA::unit(); + return c; + } + prop(c, l, r); + ll m = (l + r) / 2; + if (!c->l) c->l = new_node(l, m); + if (!c->r) c->r = new_node(m, r); + + c = copy_node(c); + if (i < m) { + c->l = set_rec(c->l, l, m, i, x); + } else { + c->r = set_rec(c->r, m, r, i, x); + } + c->x = MX::op(c->l->x, c->r->x); + return c; + } + + np multiply_rec(np c, ll l, ll r, ll i, const X &x) { + if (r == l + 1) { + c = copy_node(c); + c->x = MX::op(c->x, x); + c->lazy = MA::unit(); + return c; + } + prop(c, l, r); + ll m = (l + r) / 2; + if (!c->l) c->l = new_node(l, m); + if (!c->r) c->r = new_node(m, r); + + c = copy_node(c); + if (i < m) { + c->l = multiply_rec(c->l, l, m, i, x); + } else { + c->r = multiply_rec(c->r, m, r, i, x); + } + c->x = MX::op(c->l->x, c->r->x); + return c; + } + + void prod_rec(np c, ll l, ll r, ll ql, ll qr, X &x, A lazy) { + chmax(ql, l); + chmin(qr, r); + if (ql >= qr) return; + if (!c) { + x = MX::op(x, AM::act(default_prod(ql, qr), lazy, qr - ql)); + return; + } + if (l == ql && r == qr) { + x = MX::op(x, AM::act(c->x, lazy, r - l)); + return; + } + ll m = (l + r) / 2; + lazy = MA::op(c->lazy, lazy); + prod_rec(c->l, l, m, ql, qr, x, lazy); + prod_rec(c->r, m, r, ql, qr, x, lazy); + } + + np apply_rec(np c, ll l, ll r, ll ql, ll qr, const A &a) { + if (!c) c = new_node(l, r); + chmax(ql, l); + chmin(qr, r); + if (ql >= qr) return c; + if (l == ql && r == qr) { + c = copy_node(c); + c->x = AM::act(c->x, a, r - l); + c->lazy = MA::op(c->lazy, a); + return c; + } + prop(c, l, r); + ll m = (l + r) / 2; + c = copy_node(c); + c->l = apply_rec(c->l, l, m, ql, qr, a); + c->r = apply_rec(c->r, m, r, ql, qr, a); + c->x = MX::op(c->l->x, c->r->x); + return c; + } +}; + +template +struct modint { + static constexpr u32 umod = u32(mod); + static_assert(umod < u32(1) << 31); + u32 val; + + static modint raw(u32 v) { + modint x; + x.val = v; + return x; + } + constexpr modint() : val(0) {} + constexpr modint(int x) : val((x %= mod) < 0 ? x + mod : x){}; + modint &operator+=(const modint &p) { + if ((val += p.val) >= umod) val -= umod; + return *this; + } + modint &operator-=(const modint &p) { + if ((val += umod - p.val) >= umod) val -= umod; + return *this; + } + modint &operator*=(const modint &p) { + val = u64(val) * p.val % umod; + return *this; + } + modint operator-() const { return modint::raw(val ? mod - val : u32(0)); } + modint operator+(const modint &p) const { return modint(*this) += p; } + modint operator-(const modint &p) const { return modint(*this) -= p; } + modint operator*(const modint &p) const { return modint(*this) *= p; } + bool operator==(const modint &p) const { return val == p.val; } + bool operator!=(const modint &p) const { return val != p.val; } + modint pow(ll n) const { + assert(n >= 0); + modint ret(1), mul(val); + while (n > 0) { + if (n & 1) ret *= mul; + mul *= mul; + n >>= 1; + } + return ret; + } + static constexpr int get_mod() { return mod; } +}; + +using modint998 = modint<998244353>; + +template +struct Monoid_Add { + using X = E; + using value_type = X; + static constexpr X op(const X &x, const X &y) noexcept { return x + y; } + static constexpr X inverse(const X &x) noexcept { return -x; } + static constexpr X power(const X &x, ll n) noexcept { return X(n) * x; } + static constexpr X unit() { return X(0); } + static constexpr bool commute = true; +}; + +// op(F, G) = comp(G,F), F のあとで G +template +struct Monoid_Affine { + using F = pair; + using value_type = F; + using X = value_type; + static constexpr F op(const F &x, const F &y) noexcept { return F({x.first * y.first, x.second * y.first + y.second}); } + static constexpr F inverse(const F &x) { + auto [a, b] = x; + a = K(1) / a; + return {a, a * (-b)}; + } + static constexpr K eval(const F &f, K x) noexcept { return f.first * x + f.second; } + static constexpr F unit() { return {K(1), K(0)}; } + static constexpr bool commute = false; +}; + +template +struct ActedMonoid_Sum_Affine { + using Monoid_X = Monoid_Add; + using Monoid_A = Monoid_Affine; + using X = typename Monoid_X::value_type; + using A = typename Monoid_A::value_type; + static constexpr X act(const X &x, const A &a, const ll &size) { return x * a.fi + E(size) * a.se; } +}; + +using mint = modint998; + +int get() { + int x; + scanf("%d", &x); + return x; +} + +void solve() { + int N = get(), Q = get(); + Dynamic_Lazy_SegTree, false> seg(120 * Q, 0, N); + auto root = seg.new_root(); + + FOR(Q) { + int t = get(), l = get(), r = get(); + if (t == 0) { + int b = get(), c = get(); + root = seg.apply(root, l, r, {b, c}); + } + if (t == 1) { + mint ANS = seg.prod(root, l, r); + printf("%d\n", ANS.val); + } + } +} + +signed main() { solve(); } diff --git a/data_structure/range_affine_range_sum_large_array/task.md b/data_structure/range_affine_range_sum_large_array/task.md new file mode 100644 index 000000000..cf4916199 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/task.md @@ -0,0 +1,36 @@ +## @{keyword.statement} + +@{lang.en} +Given a size $N$ interger sequence $a_0, a_1, \dots, a_{N - 1}$. Initially, $a_i = 0$ for all $i$. +Process $Q$ queries as follows: + +- `0 $l$ $r$ $b$ $c$`: For each $i = l, l+1, \dots, {r - 1}$, $a_i \gets b \times a_i + c$. +- `1 $l$ $r$`: Print $\sum_{i = l}^{r - 1} a_i \bmod @{param.MOD}$. +@{lang.ja} +長さ $N$ の整数列 $a_0, a_1, \dots, a_{N - 1}$ がある.はじめすべての $i$ について $a_i=0$ である. +$Q$ 個のクエリを処理してください. + +- `0 $l$ $r$ $b$ $c$`: 各 $i = l, l+1, \dots, {r - 1}$ について,$a_i \gets b \times a_i + c$ +- `1 $l$ $r$`: $\sum_{i = l}^{r - 1} a_i \bmod @{param.MOD}$ を出力する. +@{lang.end} + +## @{keyword.constraints} + +- $1 \leq N \leq @{param.N_MAX}$ +- $1 \leq Q \leq @{param.Q_MAX}$ +- $0 \leq l < r \leq N$ +- $1 \leq b < @{param.MOD}$ +- $0 \leq c < @{param.MOD}$ + +## @{keyword.input} + +~~~ +$N$ $Q$ +$\textrm{Query}_0$ +$\textrm{Query}_1$ +: +$\textrm{Query}_{Q - 1}$ +~~~ + +@{example.example_00} + diff --git a/data_structure/range_affine_range_sum_large_array/verifier.cpp b/data_structure/range_affine_range_sum_large_array/verifier.cpp new file mode 100644 index 000000000..656bafde2 --- /dev/null +++ b/data_structure/range_affine_range_sum_large_array/verifier.cpp @@ -0,0 +1,28 @@ +#include "testlib.h" +#include "params.h" + +int main() { + registerValidation(); + + int n = inf.readInt(1, N_MAX, "N"); + inf.readSpace(); + int q = inf.readInt(1, Q_MAX, "Q"); + inf.readChar('\n'); + + for (int i = 0; i < q; i++) { + int t = inf.readInt(0, 1, "t"); + inf.readSpace(); + int l = inf.readInt(0, n - 1, "l"); + inf.readSpace(); + inf.readInt(l + 1, n, "r"); + if (t == 0) { + inf.readSpace(); + inf.readInt(1, MOD - 1, "b"); + inf.readSpace(); + inf.readInt(0, MOD - 1, "c"); + } + inf.readChar('\n'); + } + inf.readEof(); + return 0; +} diff --git a/linear_algebra/matrix_det_arbitrary_mod/sol/charpoly.cpp b/linear_algebra/matrix_det_arbitrary_mod/sol/charpoly.cpp index e7ee24a22..c07934640 100644 --- a/linear_algebra/matrix_det_arbitrary_mod/sol/charpoly.cpp +++ b/linear_algebra/matrix_det_arbitrary_mod/sol/charpoly.cpp @@ -62,7 +62,7 @@ std::vector get_charpoly(const Matrix &M, int mod) { Matrix H(to_upper_Hessenberg(M, mod)); int n = static_cast(H.size()); std::vector> p(n + 1); - p[0] = {1}; + p[0] = std::vector { 1 }; for (int i = 1; i <= n; ++i) { const std::vector &pi_1 = p[i - 1]; std::vector &pi = p[i]; diff --git a/tree/vertex_add_range_contour_sum_on_tree/sol/correct.cpp b/tree/vertex_add_range_contour_sum_on_tree/sol/correct.cpp index 5b4ee3261..69022ec3f 100644 --- a/tree/vertex_add_range_contour_sum_on_tree/sol/correct.cpp +++ b/tree/vertex_add_range_contour_sum_on_tree/sol/correct.cpp @@ -144,7 +144,7 @@ struct PointSetRangeContourSumOnTree { for (int v : _g[c]) { if (_removed[v]) continue; - ch[v] = { v }; + ch[v] = std::vector{ v }; pq.push(v); }