From 5c271f6103efe1e4de0c119a86022074f466e69d Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 3 Jul 2024 19:27:51 +0900 Subject: [PATCH 1/3] new prob --- math/matrix_rank_mod_2/checker.cpp | 62 +++++++++++ math/matrix_rank_mod_2/gen/example_00.in | 4 + math/matrix_rank_mod_2/gen/example_01.in | 2 + math/matrix_rank_mod_2/gen/example_02.in | 3 + math/matrix_rank_mod_2/gen/lowrank.cpp | 92 ++++++++++++++++ math/matrix_rank_mod_2/gen/max.cpp | 27 +++++ math/matrix_rank_mod_2/gen/random.cpp | 27 +++++ math/matrix_rank_mod_2/gen/zero.cpp | 25 +++++ math/matrix_rank_mod_2/hash.json | 72 +++++++++++++ math/matrix_rank_mod_2/info.toml | 23 ++++ math/matrix_rank_mod_2/sol/correct.cpp | 132 +++++++++++++++++++++++ math/matrix_rank_mod_2/task.md | 33 ++++++ math/matrix_rank_mod_2/verifier.cpp | 22 ++++ 13 files changed, 524 insertions(+) create mode 100644 math/matrix_rank_mod_2/checker.cpp create mode 100644 math/matrix_rank_mod_2/gen/example_00.in create mode 100644 math/matrix_rank_mod_2/gen/example_01.in create mode 100644 math/matrix_rank_mod_2/gen/example_02.in create mode 100644 math/matrix_rank_mod_2/gen/lowrank.cpp create mode 100644 math/matrix_rank_mod_2/gen/max.cpp create mode 100644 math/matrix_rank_mod_2/gen/random.cpp create mode 100644 math/matrix_rank_mod_2/gen/zero.cpp create mode 100644 math/matrix_rank_mod_2/hash.json create mode 100644 math/matrix_rank_mod_2/info.toml create mode 100644 math/matrix_rank_mod_2/sol/correct.cpp create mode 100644 math/matrix_rank_mod_2/task.md create mode 100644 math/matrix_rank_mod_2/verifier.cpp diff --git a/math/matrix_rank_mod_2/checker.cpp b/math/matrix_rank_mod_2/checker.cpp new file mode 100644 index 000000000..6a66d5330 --- /dev/null +++ b/math/matrix_rank_mod_2/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/math/matrix_rank_mod_2/gen/example_00.in b/math/matrix_rank_mod_2/gen/example_00.in new file mode 100644 index 000000000..81ad2c48f --- /dev/null +++ b/math/matrix_rank_mod_2/gen/example_00.in @@ -0,0 +1,4 @@ +3 3 +110 +101 +011 diff --git a/math/matrix_rank_mod_2/gen/example_01.in b/math/matrix_rank_mod_2/gen/example_01.in new file mode 100644 index 000000000..3b774dab2 --- /dev/null +++ b/math/matrix_rank_mod_2/gen/example_01.in @@ -0,0 +1,2 @@ +1 1 +0 diff --git a/math/matrix_rank_mod_2/gen/example_02.in b/math/matrix_rank_mod_2/gen/example_02.in new file mode 100644 index 000000000..8d67b2657 --- /dev/null +++ b/math/matrix_rank_mod_2/gen/example_02.in @@ -0,0 +1,3 @@ +2 0 + + diff --git a/math/matrix_rank_mod_2/gen/lowrank.cpp b/math/matrix_rank_mod_2/gen/lowrank.cpp new file mode 100644 index 000000000..89b4db4c4 --- /dev/null +++ b/math/matrix_rank_mod_2/gen/lowrank.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include "random.h" +#include "../params.h" + +using namespace std; + +using ll = long long; +using u64 = unsigned long long; + +#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 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__) + +struct My_Bitset { + using T = My_Bitset; + int N; + vector dat; + + // x で埋める + My_Bitset(int N = 0, int x = 0) : N(N) { + assert(x == 0 || x == 1); + u64 v = (x == 0 ? 0 : -1); + dat.assign((N + 63) >> 6, v); + if (N) dat.back() >>= (64 * int(dat.size()) - N); + } + + class Proxy { + public: + Proxy(vector &d, int i) : dat(d), index(i) {} + operator bool() const { return (dat[index >> 6] >> (index & 63)) & 1; } + + Proxy &operator=(u64 value) { + dat[index >> 6] &= ~(u64(1) << (index & 63)); + dat[index >> 6] |= (value & 1) << (index & 63); + return *this; + } + + private: + vector &dat; + int index; + }; + + Proxy operator[](int i) { return Proxy(dat, i); } + T &operator^=(const T &p) { + assert(N == p.N); + FOR(i, dat.size()) dat[i] ^= p.dat[i]; + return *this; + } + T operator^(const T &p) const { return T(*this) ^= p; } +}; + +using BS = My_Bitset; + +vector gen_matrix(int n, int m, int r, Random &gen) { + assert(r <= m && r <= n); + vector a(n, BS(m)); + // 最初の r 行は適当に埋める + FOR(i, r) FOR(j, m) { a[i][j] = gen.uniform_bool(); } + // それ以外は最初の r 行の線形結合 + FOR(i, r, n) { + FOR(k, r) { + if (gen.uniform_bool()) a[i] ^= a[k]; + } + } + return a; +} + +int main(int, char *argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int n = gen.uniform(1, 4096); + int m = NM_MAX / n; + if (seed % 2) swap(n, m); + int rank = gen.uniform(1, min(n, m)); + + auto a = gen_matrix(n, m, rank, gen); + + printf("%d %d\n", n, m); + for (int i = 0; i < n; i++) { + string S(m, '0'); + for (int j = 0; j < m; ++j) S[j] = '0' + a[i][j]; + printf("%s\n", S.c_str()); + } + return 0; +} diff --git a/math/matrix_rank_mod_2/gen/max.cpp b/math/matrix_rank_mod_2/gen/max.cpp new file mode 100644 index 000000000..0aaaaedf7 --- /dev/null +++ b/math/matrix_rank_mod_2/gen/max.cpp @@ -0,0 +1,27 @@ +#include +#include +#include "random.h" +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int ns[] = {1, 2, 3, 4095, 4096, 4097, NM_MAX / 3, NM_MAX / 2, NM_MAX / 1}; + int n = ns[seed % 9]; + int m = NM_MAX / n; + + vector a(n, string(m, '0')); + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + a[i][j] = '0' + gen.uniform(0, MOD - 1); + } + } + + printf("%d %d\n", n, m); + for (int i = 0; i < n; i++) { printf("%s\n", a[i].c_str()); } + + return 0; +} diff --git a/math/matrix_rank_mod_2/gen/random.cpp b/math/matrix_rank_mod_2/gen/random.cpp new file mode 100644 index 000000000..f370dd254 --- /dev/null +++ b/math/matrix_rank_mod_2/gen/random.cpp @@ -0,0 +1,27 @@ +#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 = gen.uniform(1, 4096); + int m = gen.uniform(1, NM_MAX / n); + if (seed % 2) swap(n, m); + + vector a(n, string(m, '0')); + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + a[i][j] = '0' + gen.uniform(0, MOD - 1); + } + } + + printf("%d %d\n", n, m); + for (int i = 0; i < n; i++) { printf("%s\n", a[i].c_str()); } + + return 0; +} diff --git a/math/matrix_rank_mod_2/gen/zero.cpp b/math/matrix_rank_mod_2/gen/zero.cpp new file mode 100644 index 000000000..2f46c97c7 --- /dev/null +++ b/math/matrix_rank_mod_2/gen/zero.cpp @@ -0,0 +1,25 @@ +#include +#include "random.h" +#include "../params.h" + +using namespace std; + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int ns[] = {0, 0, 0, 1, NM_MAX}; + int ms[] = {0, 1, NM_MAX, 0, 0}; + + int n = ns[seed % 5]; + int m = ms[seed % 5]; + + vector a(n, string(m, '0')); + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { a[i][j] = '0' + gen.uniform(0, 1); } + } + + printf("%d %d\n", n, m); + for (int i = 0; i < n; i++) { printf("%s\n", a[i].c_str()); } + return 0; +} diff --git a/math/matrix_rank_mod_2/hash.json b/math/matrix_rank_mod_2/hash.json new file mode 100644 index 000000000..c377ee51f --- /dev/null +++ b/math/matrix_rank_mod_2/hash.json @@ -0,0 +1,72 @@ +{ + "example_00.in": "9a9320608ae06c5aa6823a1f1e54ff65f5f676cf316345329ddd20fa19b64084", + "example_00.out": "53c234e5e8472b6ac51c1ae1cab3fe06fad053beb8ebfd8977b010655bfdd3c3", + "example_01.in": "908516a06a4532ef8c3708d1fb614131df17df5acd9dc1821abf7bb3b533af43", + "example_01.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa", + "example_02.in": "53bda9e23df7ab5ae7c6aa9b48d77ab990dd3c63392ce857d6b17a1c25e255c9", + "example_02.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa", + "lowrank_00.in": "540c9d9d2b31e94bc2b9f76115ef1d563ecc8d09564766a07e360dfa0ac06cfd", + "lowrank_00.out": "0f3d5add13e3e2b7d1387d7790fe16545c72cdd3d4d27dd5175de4322fae192b", + "lowrank_01.in": "54359baace1d3cf7d7edb17d7b8b82d9339a7264332dd58804a958d09620dd0e", + "lowrank_01.out": "6e2ae11dad0616f66bbb2b6e6556f580bb987fd911d7132aa6bee2bfc7cc7b52", + "lowrank_02.in": "263e7734d3674bb5de8a495abd0682b38944980a04e08e1b5fb6249741bd02c3", + "lowrank_02.out": "25d4f2a86deb5e2574bb3210b67bb24fcc4afb19f93a7b65a057daa874a9d18e", + "lowrank_03.in": "755306dbed6274ebd013203a1719d1ccf7e541fc41151ba217189848d19d73e7", + "lowrank_03.out": "826c8d59c616a9dc6b5d5d7e53017fd8f5e8d6c9c50b2c0d687b403cb06c24fb", + "lowrank_04.in": "e283b9cb4e87f73cb15d99933e2d16291d56931a64af2a35c34cb2a144e0a31a", + "lowrank_04.out": "cb1e4876f2609cab54dbb0e3be5dfd728a7fdec0cf108b54f5f4e269a0b44e33", + "lowrank_05.in": "fc5f0a65e771816b28657a0efabe7808784618c3efbdd1a757ab81be15510048", + "lowrank_05.out": "2191001f3e1d3fe08162fb88f88719f5abecdd84b630acdd8395e98f499fd23d", + "lowrank_06.in": "86b103e5a79df29b1617541ce57cdb231460c220c5e3441f735175326915ed99", + "lowrank_06.out": "d5c6c5db0511989f8b2db87038d1fc6952a2f828e46aef7f3836d4a5d457b775", + "lowrank_07.in": "7e4bd4a087609b2471237040c054d24aa31eaec1f66acfa019ef43e9b4be0846", + "lowrank_07.out": "a93dbf1e95ddc4cfa84e9cd3cfa6c9e0e14affd79812abde4bca688224430a65", + "lowrank_08.in": "ad5a230ec52b1e4883e623b716e643af45b2cb65d2807578a82d6533d3a706c3", + "lowrank_08.out": "38c62c0e8256ed8bcb1b23a308d84d8271d6d77121b6e739a993139ee42fa950", + "lowrank_09.in": "2f0496eaa30dbd5d41ad113c59d19f9a15ab898e9d3d822c78a208dfa8badf1d", + "lowrank_09.out": "68ca3fba3b7e864770cb61aeb306d4bd4354b68ab4dd38450860c5d823e42a53", + "max_00.in": "9a497c6022f548e32bf0b46cbe4c69371af3380f73f2201416e175f51cffb634", + "max_00.out": "4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865", + "max_01.in": "8daea7bc3cb939e1da9bcda98cc3c3d6e462c69a28694377b317c7079bd97d65", + "max_01.out": "53c234e5e8472b6ac51c1ae1cab3fe06fad053beb8ebfd8977b010655bfdd3c3", + "max_02.in": "7ad71f9519747757b17b30a48f51307acf133d6d23199e615a2959aa56e1d2e6", + "max_02.out": "1121cfccd5913f0a63fec40a6ffd44ea64f9dc135c66634ba001d10bcf4302a2", + "max_03.in": "2fe8012e7f856fddccfe5f1110a60ffa4cd47476136aa734bd7a1f694a0f2b33", + "max_03.out": "93acd367386ad3b42a26b3815a580aae055ca2f18ea40258ccaa29f7e6921380", + "max_04.in": "97bd18c0f02bb361df3b43554be9f8231abed0a6d357f939968e6e974902968b", + "max_04.out": "93acd367386ad3b42a26b3815a580aae055ca2f18ea40258ccaa29f7e6921380", + "max_05.in": "e38d0c1c2d3a06c9130d48182648eedf1dd0b8da9553c170f3b164d9189b6723", + "max_05.out": "456259708fc8786bc10bab0b88400fb094dcfa9a41384d93ccd794f292e9bfbd", + "max_06.in": "c5efd80fec0d2da89bb728d4cbf6452c301d9204f07252238c87508bdbac87b2", + "max_06.out": "1121cfccd5913f0a63fec40a6ffd44ea64f9dc135c66634ba001d10bcf4302a2", + "max_07.in": "455e907e7a751669caf20395d70f8954763098d61816502dac683a4b0f55f57d", + "max_07.out": "53c234e5e8472b6ac51c1ae1cab3fe06fad053beb8ebfd8977b010655bfdd3c3", + "max_08.in": "47c48cca7e3c564714c003bad2fe3cdfd7f6a2bdea99b46f62d9a63d24c8b722", + "max_08.out": "4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865", + "random_00.in": "3e12ab311d4ca2b5ec9b41fd0d7ba01bb8a4c7f19405d6b897d4a649d8e5e6e5", + "random_00.out": "c678ad5f5ddbf099f2dbd697b367bc237132b31ec1c4daff1a2445eb648fd39a", + "random_01.in": "cbfbdedf71858aac869db0cb05fde9a905a40adbca8b5f4e8ddce098be72afda", + "random_01.out": "5ba22c28ca5e198f96731dda13761ed0853d04cfe4e0399867caf9cea15c272e", + "random_02.in": "b94d148db447a3397999787dc31f9f589df1349ff0b7424dec3ace6f096b6d83", + "random_02.out": "94357f63ecbc9f2a794d70f4d95b4a0db358191b6ae02fe472d240e367467503", + "random_03.in": "2f272b30050ec88778d40e9bf2304b791ff6ceb9171e6ca439587250079e465c", + "random_03.out": "826c8d59c616a9dc6b5d5d7e53017fd8f5e8d6c9c50b2c0d687b403cb06c24fb", + "random_04.in": "5a761aa0cab78d6c707afb9c92e779f11dbc2cdfee7a0f22181a70fd056abc3b", + "random_04.out": "cb1e4876f2609cab54dbb0e3be5dfd728a7fdec0cf108b54f5f4e269a0b44e33", + "random_05.in": "9e0b602430f6f63b079abdb20431ec2f7a3ad8605141a9f248c8131c947e164d", + "random_05.out": "2191001f3e1d3fe08162fb88f88719f5abecdd84b630acdd8395e98f499fd23d", + "random_06.in": "65a39741c1fdd0ba5b2e1a5c0675c7a30f61514119b06de235e21ed1b863f000", + "random_06.out": "0e845d15706e39a2bf66e7761bd1d838924ac20c751039cfea7c7a0fd9ac468c", + "random_07.in": "f29a1b27ee0845327ff70c00de8fccb0da511af77baa1b98f506cb9f99c51273", + "random_07.out": "0680a0a9851fc3fd269aa3c2e4f7b99ce410bfb59f33c2706b841e1787bb4b6c", + "zero_00.in": "0ccdb5a77ba5bf7687f2565a8ed97dfb9c1af45503c496fb646312239fab5101", + "zero_00.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa", + "zero_01.in": "a79122992d53d358e6bbbbb98883d64fa0c15df3bcb08ff7b65a0580870af424", + "zero_01.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa", + "zero_02.in": "0880d8255420d185e84d7d5eab595a1d1d426e47a9418734e9f42be6e6bf1d36", + "zero_02.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa", + "zero_03.in": "0604a6c7595ce951bf2aa785335c886ebdeb99063979648c1151470ae9e058b1", + "zero_03.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa", + "zero_04.in": "80f1f2384f080da81c81cfc41d65bc9443e72a60ae72642f50e9ac9a396305ed", + "zero_04.out": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" +} \ No newline at end of file diff --git a/math/matrix_rank_mod_2/info.toml b/math/matrix_rank_mod_2/info.toml new file mode 100644 index 000000000..a962249d6 --- /dev/null +++ b/math/matrix_rank_mod_2/info.toml @@ -0,0 +1,23 @@ +title = 'Rank of Matrix (Mod 2)' +timelimit = 10.0 +forum = "https://github.com/yosupo06/library-checker-problems/issues/896" + +[[tests]] + name = "example.in" + number = 3 +[[tests]] + name = "zero.cpp" + number = 5 +[[tests]] + name = "random.cpp" + number = 8 +[[tests]] + name = "max.cpp" + number = 9 +[[tests]] + name = "lowrank.cpp" + number = 10 + +[params] + NM_MAX = 16777216 + MOD = 2 diff --git a/math/matrix_rank_mod_2/sol/correct.cpp b/math/matrix_rank_mod_2/sol/correct.cpp new file mode 100644 index 000000000..8de3caa94 --- /dev/null +++ b/math/matrix_rank_mod_2/sol/correct.cpp @@ -0,0 +1,132 @@ +#include + +using namespace std; + +using ll = long long; +using u64 = unsigned long long; +template +using vc = vector; + +// https://trap.jp/post/1224/ +#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 +T floor(T a, T b) { + return a / b - (a % b && (a ^ b) < 0); +} +template +T ceil(T x, T y) { + return floor(x + y - 1, y); +} + +struct My_Bitset { + using T = My_Bitset; + int N; + vc dat; + My_Bitset(int N = 0, int x = 0) : N(N) { + assert(x == 0 || x == 1); + u64 v = (x == 0 ? 0 : -1); + dat.assign((N + 63) >> 6, v); + if (N) dat.back() >>= (64 * len(dat) - N); + } + + int size() { return N; } + class Proxy { + public: + Proxy(vc &d, int i) : dat(d), index(i) {} + operator bool() const { return (dat[index >> 6] >> (index & 63)) & 1; } + + Proxy &operator=(u64 value) { + dat[index >> 6] &= ~(u64(1) << (index & 63)); + dat[index >> 6] |= (value & 1) << (index & 63); + return *this; + } + void flip() { + dat[index >> 6] ^= (u64(1) << (index & 63)); // XOR to flip the bit + } + + private: + vc &dat; + int index; + }; + + Proxy operator[](int i) { return Proxy(dat, i); } + T &operator^=(const T &p) { + assert(N == p.N); + FOR(i, len(dat)) dat[i] ^= p.dat[i]; + return *this; + } + T operator^(const T &p) const { return T(*this) ^= p; } +}; + +using BS = My_Bitset; + +const int MAX = (1 << 24) + 10; +char BUF[MAX]; + +void solve() { + int N, M; + scanf("%d %d", &N, &M); + if (N == 0 || M == 0) { + printf("0\n"); + return; + } + bool bl = 0; + if (N > M) { + swap(N, M); + bl = 1; + } + vc a(N, BS(M)); + + if (!bl) { + FOR(i, N) { + scanf("%s", BUF); + FOR(j, M) a[i][j] = BUF[j] - '0'; + } + } else { + FOR(i, M) { + scanf("%s", BUF); + FOR(j, N) a[j][i] = BUF[j] - '0'; + } + } + + int rk = 0; + FOR(j, M) { + if (rk == N) break; + if (!a[rk][j]) { + FOR(i, rk + 1, N) if (a[i][j]) { + swap(a[rk], a[i]); + break; + } + } + if (!a[rk][j]) continue; + FOR(i, rk + 1, N) { + if (a[i][j]) { a[i] ^= a[rk]; } + } + ++rk; + } + + printf("%d\n", rk); +} + +signed main() { solve(); } diff --git a/math/matrix_rank_mod_2/task.md b/math/matrix_rank_mod_2/task.md new file mode 100644 index 000000000..de9793ac3 --- /dev/null +++ b/math/matrix_rank_mod_2/task.md @@ -0,0 +1,33 @@ +## @{keyword.statement} + +@{lang.en} +Given $N \times M$ matrix $A = \lbrace a_{ij} \rbrace$ with entries in $\mathbb{Z}/@{param.MOD}\mathbb{Z}$, print the matrix rank of $A$. + +When dealing with matrix input, please treat each row as a string concatenated with its components ($0$ or $1$). +@{lang.ja} +$\mathbb{Z}/@{param.MOD}\mathbb{Z}$ 成分の $N \times M$ 正方行列 $A=a_{ij}$ が与えられます.$A$ の階数を出力してください. + +行列の入力の際は,各行を成分($0$ または $1$)を結合した文字列として扱ってください. +@{lang.end} + + +## @{keyword.constraints} + +- $0 \leq N, M \leq @{param.NM_MAX}$ +- $0 \leq NM \leq @{param.NM_MAX}$ +- $0 \leq a_{ij} < @{param.MOD}$ + +## @{keyword.input} + +``` +$N$ +$a _ {11} \cdots a _ {1M}$ +$\vdots$ +$a _ {N1} \cdots a _ {NM}$ +``` + +## @{keyword.sample} + +@{example.example_00} + +@{example.example_01} diff --git a/math/matrix_rank_mod_2/verifier.cpp b/math/matrix_rank_mod_2/verifier.cpp new file mode 100644 index 000000000..261b85bda --- /dev/null +++ b/math/matrix_rank_mod_2/verifier.cpp @@ -0,0 +1,22 @@ +#include "params.h" +#include "testlib.h" + +int main() { + registerValidation(); + + long long n = inf.readInt(0, NM_MAX); + inf.readSpace(); + long long m = inf.readInt(0, NM_MAX); + inf.readChar('\n'); + ensure(n * m <= NM_MAX); + + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + char c = inf.readChar(); + ensure(c == '0' || c == '1'); + } + inf.readChar('\n'); + } + inf.readEof(); + return 0; +} From db72917dbb02b44b38c302a86982928de5907d55 Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 3 Jul 2024 19:32:03 +0900 Subject: [PATCH 2/3] include --- math/matrix_rank_mod_2/sol/correct.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/math/matrix_rank_mod_2/sol/correct.cpp b/math/matrix_rank_mod_2/sol/correct.cpp index 8de3caa94..81a421e5f 100644 --- a/math/matrix_rank_mod_2/sol/correct.cpp +++ b/math/matrix_rank_mod_2/sol/correct.cpp @@ -1,4 +1,8 @@ -#include +#include +#include +#include +#include +#include using namespace std; From 210b771278071b3eb8269a7c0cf0693f4e99c4a1 Mon Sep 17 00:00:00 2001 From: maspypy <45988013+maspypy@users.noreply.github.com> Date: Sun, 28 Jul 2024 01:06:41 +0900 Subject: [PATCH 3/3] Update task.md --- math/matrix_rank_mod_2/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/matrix_rank_mod_2/task.md b/math/matrix_rank_mod_2/task.md index de9793ac3..8f7d178f4 100644 --- a/math/matrix_rank_mod_2/task.md +++ b/math/matrix_rank_mod_2/task.md @@ -5,7 +5,7 @@ Given $N \times M$ matrix $A = \lbrace a_{ij} \rbrace$ with entries in $\mathbb{ When dealing with matrix input, please treat each row as a string concatenated with its components ($0$ or $1$). @{lang.ja} -$\mathbb{Z}/@{param.MOD}\mathbb{Z}$ 成分の $N \times M$ 正方行列 $A=a_{ij}$ が与えられます.$A$ の階数を出力してください. +$\mathbb{Z}/@{param.MOD}\mathbb{Z}$ 成分の $N \times M$ 正方行列 $A = \lbrace a_{ij} \rbrace$ が与えられます.$A$ の階数を出力してください. 行列の入力の際は,各行を成分($0$ または $1$)を結合した文字列として扱ってください. @{lang.end}