Skip to content

Commit

Permalink
Merge pull request yosupo06#1168 from maspypy/999
Browse files Browse the repository at this point in the history
テストケース追加(issue 999)
  • Loading branch information
NachiaVivias authored Jul 8, 2024
2 parents 7d7079a + bdbeca4 commit e2952b1
Show file tree
Hide file tree
Showing 10 changed files with 261 additions and 70 deletions.
28 changes: 14 additions & 14 deletions math/discrete_logarithm_mod/gen/even_mod.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#include <cstdlib>
#include <cstdio>
#include "random.h"
#include <iostream>

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;
}
28 changes: 14 additions & 14 deletions math/discrete_logarithm_mod/gen/even_mod_impossible.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#include <cstdlib>
#include <cstdio>
#include "random.h"
#include <iostream>

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;
}
28 changes: 14 additions & 14 deletions math/discrete_logarithm_mod/gen/max_random.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#include <cstdlib>
#include <cstdio>
#include "random.h"
#include <iostream>

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;
}
34 changes: 34 additions & 0 deletions math/discrete_logarithm_mod/gen/max_random_yes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <cstdlib>
#include <cstdio>
#include "random.h"

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<int>(0, m);
y = mod_pow(x, n, m);
printf("%d %d %d\n", x, y, m);
}
return 0;
}
69 changes: 69 additions & 0 deletions math/discrete_logarithm_mod/gen/max_random_yes_prime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <cstdlib>
#include <cstdio>
#include "random.h"

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<int>(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<int>(0, m);
y = mod_pow(x, n, m);
printf("%d %d %d\n", x, y, m);
}
return 0;
}
28 changes: 14 additions & 14 deletions math/discrete_logarithm_mod/gen/random.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#include <cstdlib>
#include <cstdio>
#include "random.h"
#include <iostream>

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;
}
67 changes: 67 additions & 0 deletions math/discrete_logarithm_mod/gen/random_prime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <cstdlib>
#include <cstdio>
#include "random.h"

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<int>(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;
}
28 changes: 14 additions & 14 deletions math/discrete_logarithm_mod/gen/small.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#include <cstdlib>
#include <cstdio>
#include "random.h"
#include <iostream>

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;
}
12 changes: 12 additions & 0 deletions math/discrete_logarithm_mod/hash.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,24 @@
"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",
"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",
Expand Down
9 changes: 9 additions & 0 deletions math/discrete_logarithm_mod/info.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,12 @@ 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
[[tests]]
name = "random_prime.cpp"
number = 2

0 comments on commit e2952b1

Please sign in to comment.