From 0b93141626e21c45bd4f40fede1f264275570a0d Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 29 May 2024 23:00:52 +0900 Subject: [PATCH 1/4] a --- .../gen/max_random_yes.cpp | 33 +++++++++ .../gen/max_random_yes_prime.cpp | 68 +++++++++++++++++++ math/discrete_logarithm_mod/hash.json | 8 +++ math/discrete_logarithm_mod/info.toml | 6 ++ 4 files changed, 115 insertions(+) create mode 100644 math/discrete_logarithm_mod/gen/max_random_yes.cpp create mode 100644 math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp diff --git a/math/discrete_logarithm_mod/gen/max_random_yes.cpp b/math/discrete_logarithm_mod/gen/max_random_yes.cpp new file mode 100644 index 000000000..a9349c590 --- /dev/null +++ b/math/discrete_logarithm_mod/gen/max_random_yes.cpp @@ -0,0 +1,33 @@ +#include "random.h" +#include + +using namespace std; +using ll = long long; + +int mod_pow(ll a, ll n, int mod) { + assert(0 <= a && a < mod && 0 <= n); + ll r = 1; + while (n) { + if (n & 1) r = r * a % mod; + a = a * a % mod, n >>= 1; + } + return r; +} + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int t = 100; + printf("%d\n", t); + for (int i = 0; i < t; i++) { + int x, y, m; + m = gen.uniform(800'000'000, 1'000'000'000); + x = gen.uniform(0, m - 1); + // y = gen.uniform(0, m - 1); + int n = gen.uniform(0, m); + y = mod_pow(x, n, m); + printf("%d %d %d\n", x, y, m); + } + return 0; +} diff --git a/math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp b/math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp new file mode 100644 index 000000000..2fa7236c3 --- /dev/null +++ b/math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp @@ -0,0 +1,68 @@ +#include "random.h" +#include + +using namespace std; +using ll = long long; + +int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); } + +int mod_pow(ll a, ll n, int mod) { + assert(0 <= a && a < mod && 0 <= n); + ll r = 1; + while (n) { + if (n & 1) r = r * a % mod; + a = a * a % mod, n >>= 1; + } + return r; +} + +bool primetest(int p) { + if (p == 2 or p == 3 or p == 5 or p == 7) return true; + if (p % 2 == 0 or p % 3 == 0 or p % 5 == 0 or p % 7 == 0) return false; + if (p < 121) return p > 1; + const int d = (p - 1) >> lowbit(p - 1); + + auto ok = [&](int a) -> bool { + ll y = mod_pow(a, d, p); + int t = d; + while (y != 1 && y != p - 1 && t != p - 1) y = y * y % p, t <<= 1; + if (y != p - 1 && t % 2 == 0) return false; + return true; + }; + for (int a: {2, 7, 61}) + if (!ok(a)) return false; + return true; +} + +int random_prime(Random& gen, int L, int R, bool safe) { + if (!safe) { + while (1) { + int p = gen.uniform(L, R); + if (primetest(p)) return p; + } + } + // L<=q=2p+1<=R + while (1) { + int p = random_prime(gen, L / 2, (R - 1) / 2, false); + int q = 2 * p + 1; + if (L <= q && q <= R && primetest(q)) return q; + } +} + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int t = 100; + printf("%d\n", t); + for (int i = 0; i < t; i++) { + int x, y, m; + m = random_prime(gen, 800'000'000, 1'000'000'000, seed % 2); + x = gen.uniform(0, m - 1); + // y = gen.uniform(0, m - 1); + int n = gen.uniform(0, m); + y = mod_pow(x, n, m); + printf("%d %d %d\n", x, y, m); + } + return 0; +} diff --git a/math/discrete_logarithm_mod/hash.json b/math/discrete_logarithm_mod/hash.json index 3109424ae..22d8f26c2 100644 --- a/math/discrete_logarithm_mod/hash.json +++ b/math/discrete_logarithm_mod/hash.json @@ -15,6 +15,14 @@ "max_random_01.out": "3d20fa14038fa831ef6f5f1ce40ea57477e0c31cb69a37e40a344c3ed9e29759", "max_random_02.in": "f8df0db7225e90dee9c246fd707900cf977d628333d830db5a55f1ec6b44ef7e", "max_random_02.out": "ec0c3dd8c8951044f03f65d15cf5646bef0c8f0ea5f9b0dc19dddb648cc67085", + "max_random_yes_00.in": "0c3ff5ec520ff0982f46611163a826141a7201a9b43628afb8caf7b41ed17776", + "max_random_yes_00.out": "d67ffa5eda63f1cafa7ba8b39004ae78614b068008012de01fe14ab75357fc50", + "max_random_yes_01.in": "26c72f6b9682ea6e9e35d7eedb1acf500c27608b1356e9aeeeddd20aba5f0264", + "max_random_yes_01.out": "26adcab8b61bde16d8847d0cf5916e31b450138a89070c0bbe068c423bf3b208", + "max_random_yes_prime_00.in": "0a5032690f61c2ef7a8a7adbd3ec9813f138c36faaa14004584a600e1c245240", + "max_random_yes_prime_00.out": "e717da350b37787a22eab3f569c069abe36f54d207a53483f382dfa7f943b38f", + "max_random_yes_prime_01.in": "aaa26e34ae6a810316d86b695a0c9dcfba4d43eed5fc3fb9ad36f76740d91ef3", + "max_random_yes_prime_01.out": "40604118afd813d11a550a7fab8830471a621807a1668d3b1c9088339eb834d3", "random_00.in": "6d3bc7d9190f55a70c976a41fc093d69eafe31e8d13f3d685528b9adc7ed0b0f", "random_00.out": "52e3d18474c762bea400014598ff5c473bd0523e7b108927a7b7dc4830357963", "random_01.in": "910f180e65d90245f25208185c5f2e4fe49392576afd62b7a1631a3b9cad4fb6", diff --git a/math/discrete_logarithm_mod/info.toml b/math/discrete_logarithm_mod/info.toml index 81f50daf6..7684f1953 100644 --- a/math/discrete_logarithm_mod/info.toml +++ b/math/discrete_logarithm_mod/info.toml @@ -20,3 +20,9 @@ forum = "https://github.com/yosupo06/library-checker-problems/issues/28" [[tests]] name = "even_mod_impossible.cpp" number = 2 +[[tests]] + name = "max_random_yes.cpp" + number = 2 +[[tests]] + name = "max_random_yes_prime.cpp" + number = 2 From 895ebb71e4ae1d95cfb54257e374267d6efc7383 Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 29 May 2024 23:02:20 +0900 Subject: [PATCH 2/4] prime --- .../gen/random_prime.cpp | 66 +++++++++++++++++++ math/discrete_logarithm_mod/info.toml | 3 + 2 files changed, 69 insertions(+) create mode 100644 math/discrete_logarithm_mod/gen/random_prime.cpp diff --git a/math/discrete_logarithm_mod/gen/random_prime.cpp b/math/discrete_logarithm_mod/gen/random_prime.cpp new file mode 100644 index 000000000..a7b901e5c --- /dev/null +++ b/math/discrete_logarithm_mod/gen/random_prime.cpp @@ -0,0 +1,66 @@ +#include "random.h" +#include + +using namespace std; +using ll = long long; + +int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); } + +int mod_pow(ll a, ll n, int mod) { + assert(0 <= a && a < mod && 0 <= n); + ll r = 1; + while (n) { + if (n & 1) r = r * a % mod; + a = a * a % mod, n >>= 1; + } + return r; +} + +bool primetest(int p) { + if (p == 2 or p == 3 or p == 5 or p == 7) return true; + if (p % 2 == 0 or p % 3 == 0 or p % 5 == 0 or p % 7 == 0) return false; + if (p < 121) return p > 1; + const int d = (p - 1) >> lowbit(p - 1); + + auto ok = [&](int a) -> bool { + ll y = mod_pow(a, d, p); + int t = d; + while (y != 1 && y != p - 1 && t != p - 1) y = y * y % p, t <<= 1; + if (y != p - 1 && t % 2 == 0) return false; + return true; + }; + for (int a: {2, 7, 61}) + if (!ok(a)) return false; + return true; +} + +int random_prime(Random& gen, int L, int R, bool safe) { + if (!safe) { + while (1) { + int p = gen.uniform(L, R); + if (primetest(p)) return p; + } + } + // L<=q=2p+1<=R + while (1) { + int p = random_prime(gen, L / 2, (R - 1) / 2, false); + int q = 2 * p + 1; + if (L <= q && q <= R && primetest(q)) return q; + } +} + +int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); + + int t = 100; + printf("%d\n", t); + for (int i = 0; i < t; i++) { + int x, y, m; + m = random_prime(gen, 800'000'000, 1'000'000'000, seed % 2); + x = gen.uniform(0, m - 1); + y = gen.uniform(0, m - 1); + printf("%d %d %d\n", x, y, m); + } + return 0; +} diff --git a/math/discrete_logarithm_mod/info.toml b/math/discrete_logarithm_mod/info.toml index 7684f1953..5da4aad19 100644 --- a/math/discrete_logarithm_mod/info.toml +++ b/math/discrete_logarithm_mod/info.toml @@ -26,3 +26,6 @@ forum = "https://github.com/yosupo06/library-checker-problems/issues/28" [[tests]] name = "max_random_yes_prime.cpp" number = 2 +[[tests]] + name = "random_prime.cpp" + number = 2 From 27a46f64f7057224175f5533ad5823050e555892 Mon Sep 17 00:00:00 2001 From: maspypy Date: Wed, 29 May 2024 23:05:24 +0900 Subject: [PATCH 3/4] upd hash --- math/discrete_logarithm_mod/hash.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/math/discrete_logarithm_mod/hash.json b/math/discrete_logarithm_mod/hash.json index 22d8f26c2..845902d7f 100644 --- a/math/discrete_logarithm_mod/hash.json +++ b/math/discrete_logarithm_mod/hash.json @@ -29,6 +29,10 @@ "random_01.out": "69171466cd8285c53a9466d31645fa754c2746d455ebdfca2b70836e8201539c", "random_02.in": "424804bdba4d53a917cbc9a8f14268fab6a1d5bb16cbc4c7995316fb2b461421", "random_02.out": "e65b0bd71aed43602f039a4c26e9d376def95f6406ce5019c3b676f04a882ee8", + "random_prime_00.in": "17d7ef416b422c6acf98c616d53bbe200393f358d7b30b9854f9e8559534fcdc", + "random_prime_00.out": "d553cd816a80352e82d18819a9d83b8c8d42093509ce363186d4b896e498ab4a", + "random_prime_01.in": "fc97c825ab7d0348c37d1abff389aa3e258b63485a38aa0009f7fabfd8144248", + "random_prime_01.out": "64c0a36706b867a0af3a42b676d58425e548870fb2ad39d415919567ccd456d7", "small_00.in": "867abef033b2ee295d89026d7c8068a25bf4c1551f15dfa4ef57c3c72761078c", "small_00.out": "056cb39bcc4c91b5304f0e3e3d32f292f346862b9abc9fbe883962e925d2499f", "small_01.in": "97166d95be1fecc4593fc84f1f6e4de2aa2250b965606f53ab6282ea780bcbe6", From bdbeca4f5f91e0903ec7e4e5de3f62822fcd41f3 Mon Sep 17 00:00:00 2001 From: maspypy Date: Sun, 2 Jun 2024 20:43:45 +0900 Subject: [PATCH 4/4] include --- math/discrete_logarithm_mod/gen/even_mod.cpp | 28 +++++++++---------- .../gen/even_mod_impossible.cpp | 28 +++++++++---------- .../discrete_logarithm_mod/gen/max_random.cpp | 28 +++++++++---------- .../gen/max_random_yes.cpp | 3 +- .../gen/max_random_yes_prime.cpp | 3 +- math/discrete_logarithm_mod/gen/random.cpp | 28 +++++++++---------- .../gen/random_prime.cpp | 3 +- math/discrete_logarithm_mod/gen/small.cpp | 28 +++++++++---------- 8 files changed, 76 insertions(+), 73 deletions(-) diff --git a/math/discrete_logarithm_mod/gen/even_mod.cpp b/math/discrete_logarithm_mod/gen/even_mod.cpp index 4824e3074..aca71df2c 100644 --- a/math/discrete_logarithm_mod/gen/even_mod.cpp +++ b/math/discrete_logarithm_mod/gen/even_mod.cpp @@ -1,22 +1,22 @@ +#include +#include #include "random.h" -#include using namespace std; using ll = long long; int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); - long long seed = atoll(argv[1]); - auto gen = Random(seed); - - int t = 100; - printf("%d\n", t); - for (int i = 0; i < t; i++) { - int x, y, m; - m = gen.uniform(800'000'000 / 2, 1'000'000'000 / 2) * 2; - x = gen.uniform(0, m - 1); - y = gen.uniform(0, m - 1); - printf("%d %d %d\n", x, y, m); - } - return 0; + int t = 100; + printf("%d\n", t); + for (int i = 0; i < t; i++) { + int x, y, m; + m = gen.uniform(800'000'000 / 2, 1'000'000'000 / 2) * 2; + x = gen.uniform(0, m - 1); + y = gen.uniform(0, m - 1); + printf("%d %d %d\n", x, y, m); + } + return 0; } diff --git a/math/discrete_logarithm_mod/gen/even_mod_impossible.cpp b/math/discrete_logarithm_mod/gen/even_mod_impossible.cpp index 857dea500..d46cdfc4f 100644 --- a/math/discrete_logarithm_mod/gen/even_mod_impossible.cpp +++ b/math/discrete_logarithm_mod/gen/even_mod_impossible.cpp @@ -1,22 +1,22 @@ +#include +#include #include "random.h" -#include using namespace std; using ll = long long; int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); - long long seed = atoll(argv[1]); - auto gen = Random(seed); - - int t = 100; - printf("%d\n", t); - for (int i = 0; i < t; i++) { - int x, y, m; - m = gen.uniform(800'000'000 / 2, 1'000'000'000 / 2) * 2; - x = gen.uniform(0, m / 2 - 1) * 2; - y = gen.uniform(0, m / 2 - 1) * 2 + 1; - printf("%d %d %d\n", x, y, m); - } - return 0; + int t = 100; + printf("%d\n", t); + for (int i = 0; i < t; i++) { + int x, y, m; + m = gen.uniform(800'000'000 / 2, 1'000'000'000 / 2) * 2; + x = gen.uniform(0, m / 2 - 1) * 2; + y = gen.uniform(0, m / 2 - 1) * 2 + 1; + printf("%d %d %d\n", x, y, m); + } + return 0; } diff --git a/math/discrete_logarithm_mod/gen/max_random.cpp b/math/discrete_logarithm_mod/gen/max_random.cpp index c803b8993..35c81734f 100644 --- a/math/discrete_logarithm_mod/gen/max_random.cpp +++ b/math/discrete_logarithm_mod/gen/max_random.cpp @@ -1,22 +1,22 @@ +#include +#include #include "random.h" -#include using namespace std; using ll = long long; int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); - long long seed = atoll(argv[1]); - auto gen = Random(seed); - - int t = 100; - printf("%d\n", t); - for (int i = 0; i < t; i++) { - int x, y, m; - m = gen.uniform(800'000'000, 1'000'000'000); - x = gen.uniform(0, m - 1); - y = gen.uniform(0, m - 1); - printf("%d %d %d\n", x, y, m); - } - return 0; + int t = 100; + printf("%d\n", t); + for (int i = 0; i < t; i++) { + int x, y, m; + m = gen.uniform(800'000'000, 1'000'000'000); + x = gen.uniform(0, m - 1); + y = gen.uniform(0, m - 1); + printf("%d %d %d\n", x, y, m); + } + return 0; } diff --git a/math/discrete_logarithm_mod/gen/max_random_yes.cpp b/math/discrete_logarithm_mod/gen/max_random_yes.cpp index a9349c590..7c1a272b8 100644 --- a/math/discrete_logarithm_mod/gen/max_random_yes.cpp +++ b/math/discrete_logarithm_mod/gen/max_random_yes.cpp @@ -1,5 +1,6 @@ +#include +#include #include "random.h" -#include using namespace std; using ll = long long; diff --git a/math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp b/math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp index 2fa7236c3..199f64cb9 100644 --- a/math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp +++ b/math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp @@ -1,5 +1,6 @@ +#include +#include #include "random.h" -#include using namespace std; using ll = long long; diff --git a/math/discrete_logarithm_mod/gen/random.cpp b/math/discrete_logarithm_mod/gen/random.cpp index 8bdceddef..a63071428 100644 --- a/math/discrete_logarithm_mod/gen/random.cpp +++ b/math/discrete_logarithm_mod/gen/random.cpp @@ -1,22 +1,22 @@ +#include +#include #include "random.h" -#include using namespace std; using ll = long long; int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); - long long seed = atoll(argv[1]); - auto gen = Random(seed); - - int t = gen.uniform(1, 100); - printf("%d\n", t); - for (int i = 0; i < t; i++) { - int x, y, m; - m = gen.uniform(1, 1'000'000'000); - x = gen.uniform(0, m - 1); - y = gen.uniform(0, m - 1); - printf("%d %d %d\n", x, y, m); - } - return 0; + int t = gen.uniform(1, 100); + printf("%d\n", t); + for (int i = 0; i < t; i++) { + int x, y, m; + m = gen.uniform(1, 1'000'000'000); + x = gen.uniform(0, m - 1); + y = gen.uniform(0, m - 1); + printf("%d %d %d\n", x, y, m); + } + return 0; } diff --git a/math/discrete_logarithm_mod/gen/random_prime.cpp b/math/discrete_logarithm_mod/gen/random_prime.cpp index a7b901e5c..1d14c3793 100644 --- a/math/discrete_logarithm_mod/gen/random_prime.cpp +++ b/math/discrete_logarithm_mod/gen/random_prime.cpp @@ -1,5 +1,6 @@ +#include +#include #include "random.h" -#include using namespace std; using ll = long long; diff --git a/math/discrete_logarithm_mod/gen/small.cpp b/math/discrete_logarithm_mod/gen/small.cpp index 61a2e21b1..d2a19c38d 100644 --- a/math/discrete_logarithm_mod/gen/small.cpp +++ b/math/discrete_logarithm_mod/gen/small.cpp @@ -1,22 +1,22 @@ +#include +#include #include "random.h" -#include using namespace std; using ll = long long; int main(int, char* argv[]) { + long long seed = atoll(argv[1]); + auto gen = Random(seed); - long long seed = atoll(argv[1]); - auto gen = Random(seed); - - int t = 100; - printf("%d\n", t); - for (int i = 0; i < t; i++) { - int x, y, m; - m = gen.uniform(1, 10); - x = gen.uniform(0, m - 1); - y = gen.uniform(0, m - 1); - printf("%d %d %d\n", x, y, m); - } - return 0; + int t = 100; + printf("%d\n", t); + for (int i = 0; i < t; i++) { + int x, y, m; + m = gen.uniform(1, 10); + x = gen.uniform(0, m - 1); + y = gen.uniform(0, m - 1); + printf("%d %d %d\n", x, y, m); + } + return 0; }