Skip to content

Commit

Permalink
Merge pull request #1100 from Misuki743/master
Browse files Browse the repository at this point in the history
Add problem "mul_modp_convolution"
  • Loading branch information
NachiaVivias authored Jan 28, 2024
2 parents 29db25e + e89b8b5 commit d85f451
Show file tree
Hide file tree
Showing 15 changed files with 1,515 additions and 0 deletions.
976 changes: 976 additions & 0 deletions math/mul_modp_convolution/acl.h

Large diffs are not rendered by default.

62 changes: 62 additions & 0 deletions math/mul_modp_convolution/checker.cpp
Original file line number Diff line number Diff line change
@@ -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");
}
}
21 changes: 21 additions & 0 deletions math/mul_modp_convolution/gen/all_zero.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <cstdio>
#include "../params.h"
#include "random.h"

using namespace std;

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);

int P = vector{2, 3, 5, 7}[seed];

vector<int> a(P, 0), b(P, 0);

printf("%d\n", P);
for(int i = 0; i < P; i++)
printf("%d%c", a[i], " \n"[i + 1 == P]);
for(int i = 0; i < P; i++)
printf("%d%c", b[i], " \n"[i + 1 == P]);

return 0;
}
3 changes: 3 additions & 0 deletions math/mul_modp_convolution/gen/example_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
5
9 7 5 3 1
8 6 4 2 0
3 changes: 3 additions & 0 deletions math/mul_modp_convolution/gen/example_01.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
2
0 998244352
0 998244352
37 changes: 37 additions & 0 deletions math/mul_modp_convolution/gen/large.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <cstdio>
#include "../params.h"
#include "random.h"

using namespace std;

bool isPrime(int x) {
if (x < 2) return false;
for(int i = 2; i * i <= x; i++) {
if (x % i == 0) return false;
}
return true;
}

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int P = -1;
do {
P = gen.uniform(1LL << (13 + seed), 1LL << (14 + seed));
} while(!isPrime(P));

vector<int> a(P), b(P);
for(int &x : a)
x = gen.uniform(0LL, MOD - 1);
for(int &x : b)
x = gen.uniform(0LL, MOD - 1);

printf("%d\n", P);
for(int i = 0; i < P; i++)
printf("%d%c", a[i], " \n"[i + 1 == P]);
for(int i = 0; i < P; i++)
printf("%d%c", b[i], " \n"[i + 1 == P]);

return 0;
}
37 changes: 37 additions & 0 deletions math/mul_modp_convolution/gen/medium.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <cstdio>
#include "../params.h"
#include "random.h"

using namespace std;

bool isPrime(int x) {
if (x < 2) return false;
for(int i = 2; i * i <= x; i++) {
if (x % i == 0) return false;
}
return true;
}

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int P = -1;
do {
P = gen.uniform(1LL << (7 + seed / 2), 1LL << (8 + seed / 2));
} while(!isPrime(P));

vector<int> a(P), b(P);
for(int &x : a)
x = gen.uniform(0LL, MOD - 1);
for(int &x : b)
x = gen.uniform(0LL, MOD - 1);

printf("%d\n", P);
for(int i = 0; i < P; i++)
printf("%d%c", a[i], " \n"[i + 1 == P]);
for(int i = 0; i < P; i++)
printf("%d%c", b[i], " \n"[i + 1 == P]);

return 0;
}
26 changes: 26 additions & 0 deletions math/mul_modp_convolution/gen/p_max.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <cstdio>
#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 P = 524287;

vector<int> a(P), b(P);
for(int &x : a)
x = gen.uniform(0LL, MOD - 1);
for(int &x : b)
x = gen.uniform(0LL, MOD - 1);

printf("%d\n", P);
for(int i = 0; i < P; i++)
printf("%d%c", a[i], " \n"[i + 1 == P]);
for(int i = 0; i < P; i++)
printf("%d%c", b[i], " \n"[i + 1 == P]);

return 0;
}
37 changes: 37 additions & 0 deletions math/mul_modp_convolution/gen/small.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <cstdio>
#include "../params.h"
#include "random.h"

using namespace std;

bool isPrime(int x) {
if (x < 2) return false;
for(int i = 2; i * i <= x; i++) {
if (x % i == 0) return false;
}
return true;
}

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int P = -1;
do {
P = gen.uniform(1LL << (1 + seed / 2), 1LL << (2 + seed / 2));
} while(!isPrime(P));

vector<int> a(P), b(P);
for(int &x : a)
x = gen.uniform(0LL, MOD - 1);
for(int &x : b)
x = gen.uniform(0LL, MOD - 1);

printf("%d\n", P);
for(int i = 0; i < P; i++)
printf("%d%c", a[i], " \n"[i + 1 == P]);
for(int i = 0; i < P; i++)
printf("%d%c", b[i], " \n"[i + 1 == P]);

return 0;
}
82 changes: 82 additions & 0 deletions math/mul_modp_convolution/hash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"all_zero_00.in": "a5a9ddc641534c3d4bd22d72fe09c3a0a84f2a6e2fe0b464a94526011a6648c3",
"all_zero_00.out": "0ccdb5a77ba5bf7687f2565a8ed97dfb9c1af45503c496fb646312239fab5101",
"all_zero_01.in": "0ae85bf2668ab72828d38940f8acd75e6f96ce3a57279a45022767a2700bf7b6",
"all_zero_01.out": "a17138988e1387532b5cb0bd7a23f18a11d537123873e67154dada3c6359e53e",
"all_zero_02.in": "cbe2c71271326563539f7b0cde1d98b0dce2958afd9cc609c04d045b32f23c10",
"all_zero_02.out": "ac3b2ba16115668f6162cec888617fa6622221fa8ab914a47ef2dac269786408",
"all_zero_03.in": "1643f978318fbad45f46f8d51b228ca8fa1cb3ddc232cf666509095c5e37ec76",
"all_zero_03.out": "2746d8486443c0620601af45735b57713a2639346594473fff944397c58354f5",
"example_00.in": "c4f2ded53945595ea6810361ff989cb2d315cc29ec814b1ac20ddf1b54ffccc0",
"example_00.out": "5ad409216d5e5a4b34cef3a1da1677d0729b20dfdade1b9f9927cd2bb35b8d72",
"example_01.in": "1d260cb21edc8102038398f0cd547dee3a90fe7aeafe33411d1bd63886d7c597",
"example_01.out": "a79122992d53d358e6bbbbb98883d64fa0c15df3bcb08ff7b65a0580870af424",
"large_00.in": "2a7cadac624ac022773fff58c465700a8609e89da527b312d645d6151a07de5c",
"large_00.out": "f4ae889000c652858269b70ce2f30ac63fb67fe3d7958d397f388416297f953e",
"large_01.in": "14e66370180290f5175db8019a38a2c8f44824ac635c64456a35457201e0880b",
"large_01.out": "d84de515715aca7a2117914e517ee5f46e3e8785e7e7c79b8aa25494eba2afed",
"large_02.in": "c7b903a42642ba282b15a71bd1cf0fcb6423c81edae7f9e1a2a1fa7fe276c5f5",
"large_02.out": "6dcbe8ef4ff99a486c5ed1f81420385e81235c04ff6f91e9ca475447f037b649",
"large_03.in": "f3104bd582ff3d89dbfe42732dfb3ebbfd7dfcb4c6c5819bc6e4e1333bf44125",
"large_03.out": "b30fda6f19b72a0437af254dc7371524c78e6555ffdbe37432891ba1b589b65c",
"large_04.in": "ee65e9b78b3919d929e6e451ebf40e36c7b44051de96cb06312126a1c9c479c1",
"large_04.out": "0e3e6f2391a94f34a7f5a549b616659fe0f0073dcdaeaa184333fbb9e05f107b",
"large_05.in": "b8ece3ba4bc4673a2d5014d9afe5ae090785efe5569d1e250605848a82af2511",
"large_05.out": "494252a9199a5fb43ed84c3c3790c3a4227e1443088a423acadd7c73e24c95ee",
"medium_00.in": "1ffe7e0767ffa3a66105409c4fb0930757461c6f113ee4739acca9925b8e6093",
"medium_00.out": "4c8483d2a04507d020ad28b1970e90cd2ef58648f5e1251fc0fbd58d72c7d32a",
"medium_01.in": "6e270887a75f2ebb697f6658c1648d275de6c2d418057614ab92d3757b88548b",
"medium_01.out": "ea19fbc69280e599e9c390c980f5bb0182a4c8cbe1b1536fcd4480a7a3335c74",
"medium_02.in": "8fd506ca11588fa2fa559ad779036a6afa5e4f29728c8e5e2e4e3eb37ac66bb5",
"medium_02.out": "dc1faf5b006652fa0102a8d4e09f71c7f880e19c28df853ab02029477e946b8b",
"medium_03.in": "e53a3e4e16532cd9623fab61388daec6e8ab5a4d2c30d78dff82f046dfc611ca",
"medium_03.out": "9c5ad3954c4132dcb192144ea58990713c5c75bdb39d574018c85c38ef2976a0",
"medium_04.in": "b2b5966da72930255fe6af05bb4d28993c2594c696b1db0c3138258713a75668",
"medium_04.out": "d34cd2ff68aa3383b7ce15800368d5232d3a1b1fcd8cc53a25c45a4d9acba36e",
"medium_05.in": "d506fa087f4eb478bb0fdd8f2b0f30ba53856d4430c4431c0ebcca9250b6a534",
"medium_05.out": "7c7dfc2b03f46b48f9b88e21d1b2e73677afcf90bf270ad8aad52815f1352f77",
"medium_06.in": "7d4ec44662cda185c295693c19233f0ff8d7f107f8486f4bc754dfc35cfd8c4e",
"medium_06.out": "d600d79e7342ebe44a55a7fac42bb483851bbb70c8ff2e31ebcebf90afd669c8",
"medium_07.in": "f59f818b5b87315b9c919629bf1f28a4e04a97365f553ca0e43b4497f1c8b8e3",
"medium_07.out": "3e9e802837a349d5a9731b67930a25f430f54bf5b0f3fb6fbab02cff5be14b11",
"medium_08.in": "a98beff88dfb20540cadf15cdb812a9228729a49d7c8d9624bb35da55fa8bb3a",
"medium_08.out": "2f8fbdefccc85408a7ab5b8e741d1fadf2d27e239d9a6a5a516a814d25b615ce",
"medium_09.in": "8eae17b11845403777d60868a9d3a9e9a878ab5858834c29d10b0488bf37f1ec",
"medium_09.out": "e06b26973027c86ef8a35ba5ec087b8754e684931b5e80ad4f4315b32019c461",
"medium_10.in": "7b12b748cd86ac768159dbe3f9db8c6ef3d1ceb268649b723b29f6fc9b1de74c",
"medium_10.out": "db23a25b51b705960b538040388759fba52312d30ae9ccf3e9d37a427f80fd62",
"medium_11.in": "88c72d3bd6a19cdcc5cfb578f250a115bdf34403b7befd612f03c36c2460a704",
"medium_11.out": "c420a76484f411a182a4a0225d102c41e1bd6e177b4ba0009d5ce14c2e999ee1",
"p_max_00.in": "1a30706376f5666923ca2738fe912aee6881ea23c69cc9fe982a47e9eeba2a81",
"p_max_00.out": "7b1e4a204a08890057f322002fb5a3e6ad432a169d01c7a357b70fd7903ba3bf",
"p_max_01.in": "93fa7f75c054cf671acdd0fc7c10c0c4c125ffbad4f32e64a10ae4dc454e1d79",
"p_max_01.out": "aa862cee8555bf0dacaae7b9c4c5ca3138ae7131a8f88adc0620dec14f77bf78",
"p_max_02.in": "a1927ff802d4ee74f2b9270663c807681e0ab3f49e58c43af8b2380542304f51",
"p_max_02.out": "87de1fd4d1b0519077a4ab473ed8b1a5d9d1b1212d0e0d6a1e8082daf6bfe74d",
"p_max_03.in": "4fee55c7ce48af0dfb4559f358bb4259be80b0b813d0f39be64b2aaabd58aafd",
"p_max_03.out": "fc7a2b2627183fdb7a0db5e5ff9da0a58d0a896de429e21fdcfd2235a1f2f124",
"small_00.in": "13d16dd0624d642f0af0f9320f30c1da7d2692b75b3bd30ca6c1711e2e75ba43",
"small_00.out": "8195b926996865d730b5ae08409670085fc830d4623089c6a32df3f9aadcd840",
"small_01.in": "6dd28273f9134b93a055da197b48e2264e301e1c6160aee7ed1aadca65444bc2",
"small_01.out": "33f3a76ca826c81c2dbf0c162cf15d1df1707ca28b7b07414b906f3fffb92c22",
"small_02.in": "7ae8bbd3aaef17c275ffd3536f76e16d06eacdb915c83acf45275dd06d5f8e80",
"small_02.out": "38a4b5f582ab22673e941d6760555223d0ec4671d7081f2e738d59a7c5d28ce2",
"small_03.in": "1e7719cb8aec55cf8666beb5fe7575037194847937a95cc9eb511c6475abeac3",
"small_03.out": "0d2768a74938bf3219203729777dadcfb7b40cccb35e5114e9f060cd9db4d627",
"small_04.in": "549841a114c97bc5998e354753fb5cb905b1559418ef8a6190ee529a4e4c3987",
"small_04.out": "533bcea72b8f737da297cc1a5e89e1f4080dca3e233f6ac88c5211c25bcb7849",
"small_05.in": "fe58ff939a2f2f6eacf0ad997cdbc3b780229b4c111680e73ca6dedd7fc837c7",
"small_05.out": "a958f22019e2605f64c37d903359f4b5bb2300059c404fd2499871b97d626ff9",
"small_06.in": "57cf0e0f567cf35ed1956e1e5c67d944ae47f375108daf7441b32da67b9ea30a",
"small_06.out": "16bfa55a822dcb333d8b0cc73462a47fc505461128752a08886a0a4ece5857d9",
"small_07.in": "d362da46ade2435c60fa1c414a571455b90212935c16b3beadfcbed7745d2f8f",
"small_07.out": "be000427c0705ce090323a44cc804bad149f2ae283748306329f9bad8b993b88",
"small_08.in": "eb89177015e919941d43b2f6738581d00fbef332dece856ffeabb41aed9a476b",
"small_08.out": "3ce36b1ba33d20513a7169df904da04cbbcaae3caae6c2c32b41423c8ec78875",
"small_09.in": "04b7ebd6651b41aa05cc06ac89fc97e4ac9555489b2c55fbf6caa6cc27a9c42f",
"small_09.out": "8abefc0451d5b7d63c638d1716642a4fb312441b19a1b481959dc0be5249fe8d",
"small_10.in": "2f5188622e738d6583c5f4a1ebe87f424059417b50e86e427f241b6060a8eccd",
"small_10.out": "f974aabe273078122b4d59858fc9a1a95b6604f8d1f17daffe2f9d2331c7b07a",
"small_11.in": "6cc436eed5389d460823a6be013d71a66d43e4ee66f53d7e07985de0f9356d0d",
"small_11.out": "c7a44f93865b0dc2e711c2b487ec8ec0c9fee411aea67a148dfdb9999b322c48"
}
31 changes: 31 additions & 0 deletions math/mul_modp_convolution/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
title = 'Convolution on the Multiplicative Monoid of $\mathbb{Z} / P\mathbb{Z}$'
timelimit = 5.0
forum = "https://github.com/yosupo06/library-checker-problems/issues/1087"

[[solutions]]
name = "naive.cpp"
allow_re = true

[[tests]]
name = "example.in"
number = 2
[[tests]]
name = "small.cpp"
number = 12
[[tests]]
name = "medium.cpp"
number = 12
[[tests]]
name = "large.cpp"
number = 6
[[tests]]
name = "p_max.cpp"
number = 4
[[tests]]
name = "all_zero.cpp"
number = 4

[params]
P_MIN = 2
P_MAX = 524_288
MOD = 998_244_353
Loading

0 comments on commit d85f451

Please sign in to comment.