From b8890fe2bad33b7a7ccdaa7180de6e903d6a4846 Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 30 Oct 2024 00:57:59 +0900 Subject: [PATCH 1/6] newprob --- .../range_set_equal_range_query/checker.cpp | 62 +++++ .../gen/example_00.in | 14 ++ .../gen/fragment.cpp | 41 +++ .../gen/max_random.cpp | 35 +++ .../gen/random.cpp | 35 +++ .../gen/slide_window.cpp | 59 +++++ .../range_set_equal_range_query/gen/small.cpp | 35 +++ .../gen/small_kind.cpp | 52 ++++ .../gen/small_random.cpp | 35 +++ .../range_set_equal_range_query/hash.json | 66 +++++ .../range_set_equal_range_query/info.toml | 36 +++ .../sol/correct.cpp | 236 ++++++++++++++++++ .../range_set_equal_range_query/sol/naive.cpp | 51 ++++ .../range_set_equal_range_query/task.md | 45 ++++ .../range_set_equal_range_query/verifier.cpp | 34 +++ 15 files changed, 836 insertions(+) create mode 100644 data_structure/range_set_equal_range_query/checker.cpp create mode 100644 data_structure/range_set_equal_range_query/gen/example_00.in create mode 100644 data_structure/range_set_equal_range_query/gen/fragment.cpp create mode 100644 data_structure/range_set_equal_range_query/gen/max_random.cpp create mode 100644 data_structure/range_set_equal_range_query/gen/random.cpp create mode 100644 data_structure/range_set_equal_range_query/gen/slide_window.cpp create mode 100644 data_structure/range_set_equal_range_query/gen/small.cpp create mode 100644 data_structure/range_set_equal_range_query/gen/small_kind.cpp create mode 100644 data_structure/range_set_equal_range_query/gen/small_random.cpp create mode 100644 data_structure/range_set_equal_range_query/hash.json create mode 100644 data_structure/range_set_equal_range_query/info.toml create mode 100644 data_structure/range_set_equal_range_query/sol/correct.cpp create mode 100644 data_structure/range_set_equal_range_query/sol/naive.cpp create mode 100644 data_structure/range_set_equal_range_query/task.md create mode 100644 data_structure/range_set_equal_range_query/verifier.cpp diff --git a/data_structure/range_set_equal_range_query/checker.cpp b/data_structure/range_set_equal_range_query/checker.cpp new file mode 100644 index 000000000..6a66d5330 --- /dev/null +++ b/data_structure/range_set_equal_range_query/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_set_equal_range_query/gen/example_00.in b/data_structure/range_set_equal_range_query/gen/example_00.in new file mode 100644 index 000000000..7c1ed441c --- /dev/null +++ b/data_structure/range_set_equal_range_query/gen/example_00.in @@ -0,0 +1,14 @@ +8 12 +2 2 3 3 3 4 3 3 +1 0 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 7 +0 3 5 2 +1 3 +0 1 6 3 +1 3 diff --git a/data_structure/range_set_equal_range_query/gen/fragment.cpp b/data_structure/range_set_equal_range_query/gen/fragment.cpp new file mode 100644 index 000000000..beae11e4e --- /dev/null +++ b/data_structure/range_set_equal_range_query/gen/fragment.cpp @@ -0,0 +1,41 @@ +#include +#include +#include "../params.h" +#include "random.h" + +using namespace std; + +int main(int, char* argv[]) { + long long caseid = atoll(argv[1]); + long long seed = caseid + 100; + auto gen = Random(seed); + + int n = N_AND_Q_MAX; + int q = N_AND_Q_MAX; + + printf("%d %d\n", n, q); + for (int i = 0; i < n; i++) { + if (i) printf(" "); + int a = gen.uniform(1, A_MAX); + printf("%d", a); + } + printf("\n"); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + printf("%d ", t); + if (t == 0) { + int l = -1; + int r = -1; + int x = gen.uniform(1, A_MAX); + while (l == -1 || n < r) { + l = gen.uniform(0, n); + r = l + gen.uniform(1, 10); + } + printf("%d %d %d\n", l, r, x); + } else { + int i = gen.uniform(0, n - 1); + printf("%d\n", i); + } + } + return 0; +} diff --git a/data_structure/range_set_equal_range_query/gen/max_random.cpp b/data_structure/range_set_equal_range_query/gen/max_random.cpp new file mode 100644 index 000000000..7feef9c38 --- /dev/null +++ b/data_structure/range_set_equal_range_query/gen/max_random.cpp @@ -0,0 +1,35 @@ +#include +#include +#include "../params.h" +#include "random.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_AND_Q_MAX; + int q = N_AND_Q_MAX; + printf("%d %d\n", n, q); + for (int i = 0; i < n; i++) { + if (i) printf(" "); + int a = gen.uniform(1, A_MAX); + printf("%d", a); + } + printf("\n"); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + printf("%d ", t); + if (t == 0) { + int l, r; + tie(l, r) = gen.uniform_pair(0, n); + int x = gen.uniform(1, A_MAX); + printf("%d %d %d\n", l, r, x); + } else { + int i = gen.uniform(0, n - 1); + printf("%d\n", i); + } + } + return 0; +} diff --git a/data_structure/range_set_equal_range_query/gen/random.cpp b/data_structure/range_set_equal_range_query/gen/random.cpp new file mode 100644 index 000000000..b0c22dc4e --- /dev/null +++ b/data_structure/range_set_equal_range_query/gen/random.cpp @@ -0,0 +1,35 @@ +#include "random.h" +#include +#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(1, N_AND_Q_MAX); + int q = gen.uniform(1, N_AND_Q_MAX); + printf("%d %d\n", n, q); + for (int i = 0; i < n; i++) { + if (i) printf(" "); + int a = gen.uniform(1, A_MAX); + printf("%d", a); + } + printf("\n"); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + printf("%d ", t); + if (t == 0) { + int l, r; + tie(l, r) = gen.uniform_pair(0, n); + int x = gen.uniform(1, A_MAX); + printf("%d %d %d\n", l, r, x); + } else { + int i = gen.uniform(0, n - 1); + printf("%d\n", i); + } + } + return 0; +} diff --git a/data_structure/range_set_equal_range_query/gen/slide_window.cpp b/data_structure/range_set_equal_range_query/gen/slide_window.cpp new file mode 100644 index 000000000..729852523 --- /dev/null +++ b/data_structure/range_set_equal_range_query/gen/slide_window.cpp @@ -0,0 +1,59 @@ +#include +#include +#include "../params.h" +#include "random.h" + +using namespace std; + +int main(int, char* argv[]) { + long long caseid = atoll(argv[1]); + long long seed = caseid + 200; + auto gen = Random(seed); + + int n = N_AND_Q_MAX; + int q = N_AND_Q_MAX; + + int slide_stride = 3; + int slide_time_interval = 6; + int slide_position = 0; + int window_width = n / 2; + if (caseid == 1) { + slide_stride = -3; + slide_position = n - window_width; + } + + printf("%d %d\n", n, q); + for (int i = 0; i < n; i++) { + if (i) printf(" "); + int a = gen.uniform(1, A_MAX); + printf("%d", a); + } + printf("\n"); + for (int i = 0; i < q; i++) { + if (i % slide_time_interval == 0) { + int l = slide_position; + int r = l + window_width; + int x = gen.uniform(1, A_MAX); + printf("0 %d %d %d\n", l, r, x); + slide_position += slide_stride; + } else { + int t = gen.uniform(0, 1); + printf("%d ", t); + if (t == 0) { + // short range + int l = -1; + int r = -1; + int x = gen.uniform(1, A_MAX); + while (l == -1 || n < r) { + l = gen.uniform(0, n); + r = l + gen.uniform(1, 10); + } + printf("%d %d %d\n", l, r, x); + } else { + int i = gen.uniform(0, n - 1); + printf("%d\n", i); + } + } + } + return 0; +} diff --git a/data_structure/range_set_equal_range_query/gen/small.cpp b/data_structure/range_set_equal_range_query/gen/small.cpp new file mode 100644 index 000000000..f684f2608 --- /dev/null +++ b/data_structure/range_set_equal_range_query/gen/small.cpp @@ -0,0 +1,35 @@ +#include "random.h" +#include +#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 % 10 + 1; + int q = 1000; + printf("%d %d\n", n, q); + for (int i = 0; i < n; i++) { + if (i) printf(" "); + int a = gen.uniform(1, 10); + printf("%d", a); + } + printf("\n"); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + printf("%d ", t); + if (t == 0) { + int l, r; + tie(l, r) = gen.uniform_pair(0, n); + int x = gen.uniform(1, 10); + printf("%d %d %d\n", l, r, x); + } else { + int i = gen.uniform(0, n - 1); + printf("%d\n", i); + } + } + return 0; +} diff --git a/data_structure/range_set_equal_range_query/gen/small_kind.cpp b/data_structure/range_set_equal_range_query/gen/small_kind.cpp new file mode 100644 index 000000000..5307c0dd1 --- /dev/null +++ b/data_structure/range_set_equal_range_query/gen/small_kind.cpp @@ -0,0 +1,52 @@ +#include +#include +#include "../params.h" +#include "random.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = N_AND_Q_MAX; + int q = N_AND_Q_MAX; + printf("%d %d\n", n, q); + + int www[] = {1, 100, 10000}; + int kkk[] = {1, 2, 10}; + + int w = www[seed / 3]; + int k = kkk[seed % 3]; + vector S = gen.choice(k, 1, A_MAX); + auto get_a = [&]() -> int { + int idx = gen.uniform(0, k - 1); + return S[idx]; + }; + auto get_lr = [&]() -> pair { + int l = gen.uniform(0, n - w); + int r = l + w; + return {l, r}; + }; + + for (int i = 0; i < n; i++) { + if (i) printf(" "); + int a = get_a(); + printf("%d", a); + } + printf("\n"); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + printf("%d ", t); + if (t == 0) { + int l, r; + tie(l, r) = get_lr(); + int x = get_a(); + printf("%d %d %d\n", l, r, x); + } else { + int i = gen.uniform(0, n - 1); + printf("%d\n", i); + } + } + return 0; +} diff --git a/data_structure/range_set_equal_range_query/gen/small_random.cpp b/data_structure/range_set_equal_range_query/gen/small_random.cpp new file mode 100644 index 000000000..2b864ea13 --- /dev/null +++ b/data_structure/range_set_equal_range_query/gen/small_random.cpp @@ -0,0 +1,35 @@ +#include "random.h" +#include +#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(1, 2000); + int q = gen.uniform(1, 2000); + printf("%d %d\n", n, q); + for (int i = 0; i < n; i++) { + if (i) printf(" "); + int a = gen.uniform(1, 100); + printf("%d", a); + } + printf("\n"); + for (int i = 0; i < q; i++) { + int t = gen.uniform(0, 1); + printf("%d ", t); + if (t == 0) { + int l, r; + tie(l, r) = gen.uniform_pair(0, n); + int x = gen.uniform(1, A_MAX); + printf("%d %d %d\n", l, r, x); + } else { + int i = gen.uniform(0, n - 1); + printf("%d\n", i); + } + } + return 0; +} diff --git a/data_structure/range_set_equal_range_query/hash.json b/data_structure/range_set_equal_range_query/hash.json new file mode 100644 index 000000000..9d0d479d4 --- /dev/null +++ b/data_structure/range_set_equal_range_query/hash.json @@ -0,0 +1,66 @@ +{ + "example_00.in": "f1e11a49876bd0df4aa1de17588b5d489425df8e3fc0f62091f457beb79fa292", + "example_00.out": "2b25ecd78284065fc57149ab8117812dc2e11566e2a7538d4d555c9c15451452", + "fragment_00.in": "30404ae1b538d60b153a5c3babbcb2cb16d9f377813f41a8ef456992ef715d5e", + "fragment_00.out": "028fa78095654af8379132c85939f365cc3de79902b4c0189ebd6432c96afa69", + "fragment_01.in": "287eb73840547386d02977db8e2e09b0716756a3f0175012dfeb1eb85680e308", + "fragment_01.out": "d6c8b8eb4795e17caa9965ec60b94b3292b3fec6d2a65dfbe4224432de2bf2b9", + "max_random_00.in": "9d494e469dd3754c9172fb2911ab93b78c1e6e1dcadb308d464344cebef9b8c9", + "max_random_00.out": "28e9186ff17b68684f0a15bbbef99254454ff5d5bf9df0207140551ddb1267f2", + "max_random_01.in": "86139e45991f23970180cfdf4900855b86ad3a4aad210904a3b11f3b8d64af06", + "max_random_01.out": "567f40e8d60ea39c250271c2c234a749fe27b3d747ef08aefca0c80db42751f9", + "max_random_02.in": "f677e9ae75d513e917c870cfc50b86b083787318636584af4543499b7fa998ae", + "max_random_02.out": "5851c06d16df00e04aacbb487420800322521b78c96fe62a027437475fc4973b", + "random_00.in": "45eda37057e410beed029db57719773156e9bdffb615c0e65fee14cb71afb65e", + "random_00.out": "dfcab10cf0af34313dbd9a2246a11d62506032e59a416b4fb4dcfdc3cf114c93", + "random_01.in": "917f6acaa995bfe4b6ff5c73fae31c6506daebafc0cbcdbf6dddfefbb451557b", + "random_01.out": "b9da4dab764222ac22295e9e585ba9e807231bcb7548a31e21e5337d34892e85", + "random_02.in": "c072a5dbbe4f02aa0639c2a490a0f2a525d8d8dd954e719879ccb85b61b821b5", + "random_02.out": "2dca28d635c087a31b87288d2e79d91ce4d1e66f0af07bb859be8f167c94e3c2", + "slide_window_00.in": "369b3e1c6574bc761a14350d4b5d1a3a6918618dd7aa775c988a1e5872c0b16e", + "slide_window_00.out": "6587c7c0abd3d5be771bcfdc7a0bd3b80a843beec188f5f53bbc1e1160bdecf6", + "slide_window_01.in": "61038921ccff5b12458d40ef67d525972dd2059d667ec1a0f14539e219d25b25", + "slide_window_01.out": "b99f2b9e147380b6fe27c05e5fd9adbdeaa7f832adfe741566aab5346406c106", + "small_00.in": "ffdd56f09eacb9ab915d2ee8b5abbfe3e65999dfd7b5b38a1348ab52c0204c53", + "small_00.out": "bb715343683186585d28db368766fe679746b543a66d7a6ccdf5e035f2cd52b0", + "small_01.in": "ca16cd0a123e88a7cecacb8d045547d18ffd8d450692fe7a605702af2344ae73", + "small_01.out": "48cb97f2cd515d9f118d344334413392c93a02f6655e1261b668dea9f6088c74", + "small_02.in": "0f6047cbec4b9b0119f642a2e06c3b56cceca40e46913493457ae2c51acf6dc9", + "small_02.out": "a0959487671d4270eb089b59e36c1294f1a5e912b214f3b00bf6cec559f88416", + "small_03.in": "abafe08d3bda91d3a7ef8420ce400cbb0ac06cabf048dc908921c159dfbaf865", + "small_03.out": "08b92076edaa7555d88e646ddd0ee2ba23f43a14b4a72e609862b5539db49ad2", + "small_04.in": "3ccdc911a869f934bbe2582f7e14603e532859540f31a402b83b05e4ef327fce", + "small_04.out": "a863e4ed362d25f0a4d9fedeb96b3a5dccd0bf5c1f2b01467e6c6bf5baa762d2", + "small_05.in": "b5e680fe332ccd37c9a060f153d60c076ed173a7bd417dfcf0661428b845ca92", + "small_05.out": "b886a1440138e22e3df56d08cec4441a6929a4b0394f960f9a59e5f612f91433", + "small_06.in": "f0891684b657ff3f38d334d8aa156b2cf5e446c5a69aaff744e63b326be42a71", + "small_06.out": "ed3d9c4f9e340d0e6f17effd69766d4af17365386bfdcaef4f6925b2d2fc0843", + "small_07.in": "a24176659db13247a1b1567e59c390f1afb4fc67cf1a48d8e6117ff7ec47d47e", + "small_07.out": "36460f5f5f0c0e3b300afe5d7a70e5388d429cde2ca6a6bed80b2acfdc5ba0fe", + "small_08.in": "b6ebaaf798912625768b2d8b0d247df6e0bf8fdc2a22615254e391f0e95f49f0", + "small_08.out": "1c9bfc826d218baa878698e0b3503fad5be1f2b5a4c60d231e1982ad0fecacce", + "small_09.in": "8557b1ef6d84820f7eb4ba2d80897fda724285d181bce24dc0a45e040eac1adc", + "small_09.out": "d090aa6e5f0fda823b50fd8d8fbc13d77868abc5a1058456329c9ccf105b2fac", + "small_kind_00.in": "978a369ce545b823c650a0bb934ec480ce0b619a77bb5840603a7d29e1406f8a", + "small_kind_00.out": "c72d1f0121fa163831fddb828bd8a702cd0b8a1d2cadb368ca272e27bd7cedd5", + "small_kind_01.in": "9cede1ad34b878c59d24edb83a5933652b62838d56010ea57d22749fa631bb87", + "small_kind_01.out": "d316febd54447c4c8676259406fc2e19dc042e7c6e29174bd8bb7d926f19ecce", + "small_kind_02.in": "271035129f3e65893d96af68024f479bbd9329ac8055d9110e1991953a19a5c3", + "small_kind_02.out": "28e756416a3b889f6946bf628f7d50cc882d94370a2aab396e903ee157f8adf6", + "small_kind_03.in": "2da22d10a79ad757fe13a972d290ff5e2154ba0bafe4788a68eedfd1e00e15f2", + "small_kind_03.out": "10d68cc03d9200b3a220c1fc8c42dc3dabb6714816c3b2575f481d508fc6363d", + "small_kind_04.in": "2307e304db413c8687956eceaaa25aac354093c213ae9bc1431e849e3385da4b", + "small_kind_04.out": "a1f3a51d1eac8992dc59c02410bfd12b4cd0ffa573aaa23a22a754dbecaaef8a", + "small_kind_05.in": "82e6a6eebd904d38a184cf4b5a175312780e61602cf36b6ebcfdb42da83074f7", + "small_kind_05.out": "bd52b94bb470fac5a05e3e085e8c2673b7bce4f4889d6b66899d24512ecbd46a", + "small_kind_06.in": "10c31b66634f202fc1b9358707d881b8f0bd9e261852c4ddb70af7a837588af2", + "small_kind_06.out": "a1688ac9bdac4fdba841922a7a01f95648e92441830f195b1cc93dca5b05a783", + "small_kind_07.in": "0ac91a80577b8656fc9ca264763c322b79fd7478b44fa631e18c62536956c8d2", + "small_kind_07.out": "b94b74645773615c3121c5820f1e91943660933f6adf534dab27c06309adbe0f", + "small_kind_08.in": "b46ee64be49a8b3783c2da69b6d1922341fba721b8d1193d691d78dcef6a2899", + "small_kind_08.out": "176a2bd712c838c47f6fbd0b98ff272ce849f282c5ba600d70a771a33d7a7714", + "small_random_00.in": "c148f2127ec967b34515157dc3f4b00a4c4402f0d6b57168043be1592f484b9e", + "small_random_00.out": "b757433cd257c24c2d702bc949a11d471c4f72e2cc95ad718ac809fae75bc0ca", + "small_random_01.in": "054f2af760a7829d950879664d0eb4527db6809ef1ccbf30715fdd6ff9c0306c", + "small_random_01.out": "0366b312fc2b446a8e9359bd47caf2cc6860aa49536e906e6cddcd8812053271" +} \ No newline at end of file diff --git a/data_structure/range_set_equal_range_query/info.toml b/data_structure/range_set_equal_range_query/info.toml new file mode 100644 index 000000000..4ae156f7c --- /dev/null +++ b/data_structure/range_set_equal_range_query/info.toml @@ -0,0 +1,36 @@ +title = 'Range Set Range Composite' +timelimit = 5.0 +forum = "https://github.com/yosupo06/library-checker-problems/issues/829" +[[tests]] + name = "example.in" + number = 1 + +[[tests]] + name = "small_random.cpp" + number = 2 +[[tests]] + name = "small.cpp" + number = 10 +[[tests]] + name = "random.cpp" + number = 3 +[[tests]] + name = "max_random.cpp" + number = 3 +[[tests]] + name = "fragment.cpp" + number = 2 +[[tests]] + name = "slide_window.cpp" + number = 2 +[[tests]] + name = "small_kind.cpp" + number = 9 + +[[solutions]] + name = "naive.cpp" + allow_tle = true + +[params] + N_AND_Q_MAX = 500_000 + A_MAX=1_000_000_000 diff --git a/data_structure/range_set_equal_range_query/sol/correct.cpp b/data_structure/range_set_equal_range_query/sol/correct.cpp new file mode 100644 index 000000000..46988c6a7 --- /dev/null +++ b/data_structure/range_set_equal_range_query/sol/correct.cpp @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +using ll = long long; +using u32 = uint32_t; +using u64 = uint64_t; + +template +using vc = vector; +template +using vvc = 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 + +// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2) +int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); } +int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); } +int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); } +int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); } +// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2) +int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); } +int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); } +int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); } +int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); } + +#define MIN(v) *min_element(all(v)) +#define MAX(v) *max_element(all(v)) +#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x))) +#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x))) +#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit() + +// 64-ary tree +// space: (N/63) * u64 +struct FastSet { + static constexpr u32 B = 64; + int n, log; + vvc seg; + + FastSet() {} + FastSet(int n) { build(n); } + + int size() { return n; } + + void build(int m) { + seg.clear(); + n = m; + do { + seg.push_back(vc((m + B - 1) / B)); + m = (m + B - 1) / B; + } while (m > 1); + log = seg.size(); + } + bool operator[](int i) const { return seg[0][i / B] >> (i % B) & 1; } + void insert(int i) { + assert(0 <= i && i < n); + for (int h = 0; h < log; h++) { seg[h][i / B] |= u64(1) << (i % B), i /= B; } + } + void add(int i) { insert(i); } + void erase(int i) { + assert(0 <= i && i < n); + u64 x = 0; + for (int h = 0; h < log; h++) { + seg[h][i / B] &= ~(u64(1) << (i % B)); + seg[h][i / B] |= x << (i % B); + x = bool(seg[h][i / B]); + i /= B; + } + } + void remove(int i) { erase(i); } + + // min[x,n) or n + int next(int i) { + assert(i <= n); + i = max(i, 0); + for (int h = 0; h < log; h++) { + if (i / B == seg[h].size()) break; + u64 d = seg[h][i / B] >> (i % B); + if (!d) { + i = i / B + 1; + continue; + } + i += lowbit(d); + for (int g = h - 1; g >= 0; g--) { + i *= B; + i += lowbit(seg[g][i / B]); + } + return i; + } + return n; + } + + // max [0,x], or -1 + int prev(int i) { + assert(i >= -1); + if (i >= n) i = n - 1; + for (int h = 0; h < log; h++) { + if (i == -1) break; + u64 d = seg[h][i / B] << (63 - i % B); + if (!d) { + i = i / B - 1; + continue; + } + i -= __builtin_clzll(d); + for (int g = h - 1; g >= 0; g--) { + i *= B; + i += topbit(seg[g][i / B]); + } + return i; + } + return -1; + } +}; + +template +struct Intervals_Fast { + const int LLIM, RLIM; + const T none_val; + // none_val でない区間の個数と長さ合計 + int total_num; + int total_len; + vc dat; + FastSet ss; + + Intervals_Fast(int N, T none_val) : LLIM(0), RLIM(N), none_val(none_val), total_num(0), total_len(0), dat(N, none_val), ss(N) { ss.insert(0); } + + // x を含む区間の情報の取得 l, r, t + tuple get(int x, bool ERASE = false) { + int l = ss.prev(x); + int r = ss.next(x + 1); + T t = dat[l]; + if (t != none_val && ERASE) { + --total_num, total_len -= r - l; + dat[l] = none_val; + merge_at(l); + merge_at(r); + } + return {l, r, t}; + } + + void erase_range(int L, int R) { + assert(LLIM <= L && L <= R && R <= RLIM); + if (L == R) return; + // 半端なところの分割 + int p = ss.prev(L); + if (p < L) { + ss.insert(L); + dat[L] = dat[p]; + if (dat[L] != none_val) ++total_num; + } + p = ss.next(R); + if (R < p) { + dat[R] = dat[ss.prev(R)]; + ss.insert(R); + if (dat[R] != none_val) ++total_num; + } + p = L; + while (p < R) { + int q = ss.next(p + 1); + if (dat[p] != none_val) --total_num, total_len -= q - p; + ss.erase(p); + p = q; + } + ss.insert(L); + dat[L] = none_val; + } + + void set(int L, int R, T t) { + if (L == R) return; + erase_range(L, R); + ss.insert(L); + dat[L] = t; + if (t != none_val) total_num++, total_len += R - L; + merge_at(L); + merge_at(R); + } + + void merge_at(int p) { + if (p <= 0 || RLIM <= p) return; + int q = ss.prev(p - 1); + if (dat[p] == dat[q]) { + if (dat[p] != none_val) --total_num; + ss.erase(p); + } + } +}; + +int rd() { + int x; + scanf("%d", &x); + return x; +}; + +void solve() { + int N = rd(), Q = rd(); + Intervals_Fast X(N, -1); + FOR(i, N) { + int x = rd(); + X.set(i, i + 1, x); + } + FOR(Q) { + int t = rd(); + if (t == 0) { + int l = rd(), r = rd(), x = rd(); + X.set(l, r, x); + } + if (t == 1) { + int i = rd(); + auto [l, r, x] = X.get(i); + printf("%d %d %d\n", x, l, r); + } + } +} + +signed main() { solve(); } diff --git a/data_structure/range_set_equal_range_query/sol/naive.cpp b/data_structure/range_set_equal_range_query/sol/naive.cpp new file mode 100644 index 000000000..459dee59e --- /dev/null +++ b/data_structure/range_set_equal_range_query/sol/naive.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +using namespace std; +using ll = long long; + +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__) + +int rd() { + int x; + scanf("%d", &x); + return x; +} + +void solve() { + int N = rd(), Q = rd(); + vc A(N); + FOR(i, N) A[i] = rd(); + FOR(Q) { + int t = rd(); + if (t == 0) { + int l = rd(), r = rd(), x = rd(); + FOR(i, l, r) A[i] = x; + } + if (t == 1) { + int i = rd(); + int x = A[i]; + int l = i, r = i + 1; + while (0 < l && A[l - 1] == A[i]) --l; + while (r < N && A[i] == A[r]) ++r; + printf("%d %d %d\n", x, l, r); + } + } +} + +signed main() { solve(); } diff --git a/data_structure/range_set_equal_range_query/task.md b/data_structure/range_set_equal_range_query/task.md new file mode 100644 index 000000000..bcef6d7d8 --- /dev/null +++ b/data_structure/range_set_equal_range_query/task.md @@ -0,0 +1,45 @@ +## @{keyword.statement} + +@{lang.en} +Given a size $N$ sequence of linear functions $f _ 0, f _ 1, ..., f _ {N-1}$. For all $i$, $f _ i(x) = a _ i x + b _ i$. Process $Q$ queries as follows: + +- `0 $l$ $r$ $c$ $d$`: For each $i = l, l+1, \dots, {r - 1}$, $f _ i \gets cx + d$. +- `1 $l$ $r$ $x$`: Print $f _ {r-1}(f _ {r-2}(...f _ l(x))) \bmod @{param.MOD}$. +@{lang.ja} +長さ $N$ の整数列 A=$(a _ 0, a _ 1, ..., a _ {n-1})$ が与えられます. +$Q$ 個を処理してください. + +- `0 $l$ $r$ $x$`: 各 $i = l, l+1, \dots, {r - 1}$ について,$a _ i$ を $x$ に変更する. +- `2 $i$`: $a_i$ の値および,$l\leq i < r$ かつ $a _ l = \cdots = a _ {r-1}$ を満たすような極大な区間を答える.後者はより形式的には,次によって一意に定まる $(l,r)$ である. + - $l\leq i < r$ かつ $a _ l = \cdots = a _ {r-1}$ + - $l=0$ または $a_{l-1}\neq a_i$ + - $r=N$ または $a_{r}\neq a_i$ +@{lang.end} + +## @{keyword.constraints} + +- $1 \leq N, Q \leq @{param.N_AND_Q_MAX}$ +- $1 \leq a _ i, c < @{param.MOD}$ +- $0 \leq b _ i, d, x < @{param.MOD}$ +- $0 \leq l < r \leq N$ + +## @{keyword.input} + +~~~ +$N$ $Q$ +$a _ 0$ $a _ 1$ $\cdots$ $a _ {N-1}$ +$\textrm{Query} _ 0$ +$\textrm{Query} _ 1$ +: +$\textrm{Query} _ {Q - 1}$ +~~~ + +## @{keyword.output} + +~~~ +$a _ i$ $l$ $r$ +$\vdots$ +$a _ i$ $l$ $r$ +~~~ + +@{example.example_00} diff --git a/data_structure/range_set_equal_range_query/verifier.cpp b/data_structure/range_set_equal_range_query/verifier.cpp new file mode 100644 index 000000000..885d7a0b4 --- /dev/null +++ b/data_structure/range_set_equal_range_query/verifier.cpp @@ -0,0 +1,34 @@ +#include "testlib.h" +#include "params.h" + +int main() { + registerValidation(); + + int n = inf.readInt(1, N_AND_Q_MAX, "N"); + inf.readSpace(); + int q = inf.readInt(1, N_AND_Q_MAX, "Q"); + inf.readChar('\n'); + + for (int i = 0; i < n; i++) { + if (i) inf.readSpace(); + inf.readInt(1, A_MAX, "a_i"); + } + inf.readChar('\n'); + + for (int i = 0; i < q; i++) { + int t = inf.readInt(0, 1, "t"); + inf.readSpace(); + if (t == 0) { + int l = inf.readInt(0, n - 1, "l"); + inf.readSpace(); + inf.readInt(l + 1, n, "r"); + inf.readSpace(); + inf.readInt(1, A_MAX, "a_i"); + } else { + inf.readInt(0, n - 1, "i"); + } + inf.readChar('\n'); + } + inf.readEof(); + return 0; +} From 975fe6f2f50279dd6302794c904ee72d27f54a6d Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 30 Oct 2024 01:02:06 +0900 Subject: [PATCH 2/6] upd info --- data_structure/range_set_equal_range_query/info.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/data_structure/range_set_equal_range_query/info.toml b/data_structure/range_set_equal_range_query/info.toml index 4ae156f7c..d87061050 100644 --- a/data_structure/range_set_equal_range_query/info.toml +++ b/data_structure/range_set_equal_range_query/info.toml @@ -1,6 +1,7 @@ -title = 'Range Set Range Composite' +title = 'Range Set Equal Range Query' timelimit = 5.0 -forum = "https://github.com/yosupo06/library-checker-problems/issues/829" +forum = "https://github.com/yosupo06/library-checker-problems/issues/990" + [[tests]] name = "example.in" number = 1 From f5695f7c636f05d08c8d9520701bae20481570b6 Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 30 Oct 2024 01:05:25 +0900 Subject: [PATCH 3/6] task --- data_structure/range_set_equal_range_query/task.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/data_structure/range_set_equal_range_query/task.md b/data_structure/range_set_equal_range_query/task.md index bcef6d7d8..7c047f42b 100644 --- a/data_structure/range_set_equal_range_query/task.md +++ b/data_structure/range_set_equal_range_query/task.md @@ -1,12 +1,15 @@ ## @{keyword.statement} @{lang.en} -Given a size $N$ sequence of linear functions $f _ 0, f _ 1, ..., f _ {N-1}$. For all $i$, $f _ i(x) = a _ i x + b _ i$. Process $Q$ queries as follows: +You are given an integer sequence $A = (a _ 0, a _ 1, \dots, a _ {n-1})$ of length $N$. Perform $Q$ operations. -- `0 $l$ $r$ $c$ $d$`: For each $i = l, l+1, \dots, {r - 1}$, $f _ i \gets cx + d$. -- `1 $l$ $r$ $x$`: Print $f _ {r-1}(f _ {r-2}(...f _ l(x))) \bmod @{param.MOD}$. +0 $l$ $r$ $x$: For each $i = l, l+1, \dots, r-1$, update $a _ i$ to $x$. +2 $i$: Output the value of $a _ i$ and the largest interval $(l, r)$ that satisfies $l \leq i < r$ and $a _ l = \cdots = a _ {r-1}$. Formally, $(l, r)$ is uniquely determined by the following conditions: +$l \leq i < r$ and $a _ l = \cdots = a _ {r-1}$, +$l = 0$ or $a _ {l-1} \neq a _ i$, +$r = N$ or $a _ {r} \neq a _ i$. @{lang.ja} -長さ $N$ の整数列 A=$(a _ 0, a _ 1, ..., a _ {n-1})$ が与えられます. +長さ $N$ の整数列 $A=(a _ 0, a _ 1, ..., a _ {n-1})$ が与えられます. $Q$ 個を処理してください. - `0 $l$ $r$ $x$`: 各 $i = l, l+1, \dots, {r - 1}$ について,$a _ i$ を $x$ に変更する. From 0a80d843f8d4ab71c42d57d0a36e3461bfb5c925 Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 30 Oct 2024 01:06:18 +0900 Subject: [PATCH 4/6] task --- data_structure/range_set_equal_range_query/task.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structure/range_set_equal_range_query/task.md b/data_structure/range_set_equal_range_query/task.md index 7c047f42b..dceae6082 100644 --- a/data_structure/range_set_equal_range_query/task.md +++ b/data_structure/range_set_equal_range_query/task.md @@ -22,9 +22,9 @@ $Q$ 個を処理してください. ## @{keyword.constraints} - $1 \leq N, Q \leq @{param.N_AND_Q_MAX}$ -- $1 \leq a _ i, c < @{param.MOD}$ -- $0 \leq b _ i, d, x < @{param.MOD}$ +- $1 \leq a _ i \leq @{param.A_MAX}$ - $0 \leq l < r \leq N$ +- $0 \leq i < N$ ## @{keyword.input} From 11f11fa331de133e2f5034ee5e8bebd6fbb83b44 Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 30 Oct 2024 01:07:13 +0900 Subject: [PATCH 5/6] a --- data_structure/range_set_equal_range_query/task.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data_structure/range_set_equal_range_query/task.md b/data_structure/range_set_equal_range_query/task.md index dceae6082..41b36654f 100644 --- a/data_structure/range_set_equal_range_query/task.md +++ b/data_structure/range_set_equal_range_query/task.md @@ -3,17 +3,17 @@ @{lang.en} You are given an integer sequence $A = (a _ 0, a _ 1, \dots, a _ {n-1})$ of length $N$. Perform $Q$ operations. -0 $l$ $r$ $x$: For each $i = l, l+1, \dots, r-1$, update $a _ i$ to $x$. -2 $i$: Output the value of $a _ i$ and the largest interval $(l, r)$ that satisfies $l \leq i < r$ and $a _ l = \cdots = a _ {r-1}$. Formally, $(l, r)$ is uniquely determined by the following conditions: -$l \leq i < r$ and $a _ l = \cdots = a _ {r-1}$, -$l = 0$ or $a _ {l-1} \neq a _ i$, -$r = N$ or $a _ {r} \neq a _ i$. +- 0 $l$ $r$ $x$: For each $i = l, l+1, \dots, r-1$, update $a _ i$ to $x$. +- 1 $i$: Output the value of $a _ i$ and the largest interval $(l, r)$ that satisfies $l \leq i < r$ and $a _ l = \cdots = a _ {r-1}$. Formally, $(l, r)$ is uniquely determined by the following conditions: + - $l \leq i < r$ and $a _ l = \cdots = a _ {r-1}$, + - $l = 0$ or $a _ {l-1} \neq a _ i$, + - $r = N$ or $a _ {r} \neq a _ i$. @{lang.ja} 長さ $N$ の整数列 $A=(a _ 0, a _ 1, ..., a _ {n-1})$ が与えられます. $Q$ 個を処理してください. - `0 $l$ $r$ $x$`: 各 $i = l, l+1, \dots, {r - 1}$ について,$a _ i$ を $x$ に変更する. -- `2 $i$`: $a_i$ の値および,$l\leq i < r$ かつ $a _ l = \cdots = a _ {r-1}$ を満たすような極大な区間を答える.後者はより形式的には,次によって一意に定まる $(l,r)$ である. +- `1 $i$`: $a_i$ の値および,$l\leq i < r$ かつ $a _ l = \cdots = a _ {r-1}$ を満たすような極大な区間を答える.後者はより形式的には,次によって一意に定まる $(l,r)$ である. - $l\leq i < r$ かつ $a _ l = \cdots = a _ {r-1}$ - $l=0$ または $a_{l-1}\neq a_i$ - $r=N$ または $a_{r}\neq a_i$ From 1257dd8e978c6b2c749deef1b199ddf98d027512 Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 30 Oct 2024 01:09:13 +0900 Subject: [PATCH 6/6] taks --- data_structure/range_set_equal_range_query/task.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structure/range_set_equal_range_query/task.md b/data_structure/range_set_equal_range_query/task.md index 41b36654f..582e633ac 100644 --- a/data_structure/range_set_equal_range_query/task.md +++ b/data_structure/range_set_equal_range_query/task.md @@ -1,7 +1,7 @@ ## @{keyword.statement} @{lang.en} -You are given an integer sequence $A = (a _ 0, a _ 1, \dots, a _ {n-1})$ of length $N$. Perform $Q$ operations. +You are given an integer sequence $A = (a _ 0, a _ 1, \dots, a _ {N-1})$ of length $N$. Perform $Q$ operations. - 0 $l$ $r$ $x$: For each $i = l, l+1, \dots, r-1$, update $a _ i$ to $x$. - 1 $i$: Output the value of $a _ i$ and the largest interval $(l, r)$ that satisfies $l \leq i < r$ and $a _ l = \cdots = a _ {r-1}$. Formally, $(l, r)$ is uniquely determined by the following conditions: @@ -9,7 +9,7 @@ You are given an integer sequence $A = (a _ 0, a _ 1, \dots, a _ {n-1})$ of leng - $l = 0$ or $a _ {l-1} \neq a _ i$, - $r = N$ or $a _ {r} \neq a _ i$. @{lang.ja} -長さ $N$ の整数列 $A=(a _ 0, a _ 1, ..., a _ {n-1})$ が与えられます. +長さ $N$ の整数列 $A=(a _ 0, a _ 1, ..., a _ {N-1})$ が与えられます. $Q$ 個を処理してください. - `0 $l$ $r$ $x$`: 各 $i = l, l+1, \dots, {r - 1}$ について,$a _ i$ を $x$ に変更する.