-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
--- | ||
data: | ||
_extendedDependsOn: | ||
- icon: ':heavy_check_mark:' | ||
path: number/factorize.hpp | ||
title: "Integer factorization \uFF08\u7D20\u56E0\u6570\u5206\u89E3\uFF09" | ||
- icon: ':heavy_check_mark:' | ||
path: random/xorshift.hpp | ||
title: random/xorshift.hpp | ||
_extendedRequiredBy: [] | ||
_extendedVerifiedWith: [] | ||
_isVerificationFailed: false | ||
_pathExtension: cpp | ||
_verificationStatusIcon: ':heavy_check_mark:' | ||
attributes: | ||
'*NOT_SPECIAL_COMMENTS*': '' | ||
PROBLEM: https://judge.yosupo.jp/problem/primality_test | ||
links: | ||
- https://judge.yosupo.jp/problem/primality_test | ||
bundledCode: "#line 1 \"number/test/is_prime.test.cpp\"\n#define PROBLEM \"https://judge.yosupo.jp/problem/primality_test\"\ | ||
\n#line 2 \"random/xorshift.hpp\"\n#include <cstdint>\n\n// CUT begin\nuint32_t\ | ||
\ rand_int() // XorShift random integer generator\n{\n static uint32_t x =\ | ||
\ 123456789, y = 362436069, z = 521288629, w = 88675123;\n uint32_t t = x ^\ | ||
\ (x << 11);\n x = y;\n y = z;\n z = w;\n return w = (w ^ (w >> 19))\ | ||
\ ^ (t ^ (t >> 8));\n}\ndouble rand_double() { return (double)rand_int() / UINT32_MAX;\ | ||
\ }\n#line 3 \"number/factorize.hpp\"\n#include <algorithm>\n#include <array>\n\ | ||
#include <cassert>\n#include <numeric>\n#include <vector>\n\nnamespace SPRP {\n\ | ||
// http://miller-rabin.appspot.com/\nconst std::vector<std::vector<__int128>>\ | ||
\ bases{\n {126401071349994536}, // < 291831\n\ | ||
\ {336781006125, 9639812373923155}, // < 1050535501 (1e9)\n\ | ||
\ {2, 2570940, 211991001, 3749873356}, // < 47636622961201 (4e13)\n\ | ||
\ {2, 325, 9375, 28178, 450775, 9780504, 1795265022} // <= 2^64\n};\ninline\ | ||
\ int get_id(long long n) {\n if (n < 291831) {\n return 0;\n } else\ | ||
\ if (n < 1050535501) {\n return 1;\n } else if (n < 47636622961201)\n\ | ||
\ return 2;\n else { return 3; }\n}\n} // namespace SPRP\n\n// Miller-Rabin\ | ||
\ primality test\n// https://ja.wikipedia.org/wiki/%E3%83%9F%E3%83%A9%E3%83%BC%E2%80%93%E3%83%A9%E3%83%93%E3%83%B3%E7%B4%A0%E6%95%B0%E5%88%A4%E5%AE%9A%E6%B3%95\n\ | ||
// Complexity: O(lg n) per query\nstruct {\n long long modpow(__int128 x, __int128\ | ||
\ n, long long mod) noexcept {\n __int128 ret = 1;\n for (x %= mod;\ | ||
\ n; x = x * x % mod, n >>= 1) ret = (n & 1) ? ret * x % mod : ret;\n return\ | ||
\ ret;\n }\n bool operator()(long long n) noexcept {\n if (n < 2)\ | ||
\ return false;\n if (n % 2 == 0) return n == 2;\n int s = __builtin_ctzll(n\ | ||
\ - 1);\n\n for (__int128 a : SPRP::bases[SPRP::get_id(n)]) {\n \ | ||
\ if (a % n == 0) continue;\n a = modpow(a, (n - 1) >> s, n);\n\ | ||
\ bool may_composite = true;\n if (a == 1) continue;\n \ | ||
\ for (int r = s; r--; a = a * a % n) {\n if (a == n\ | ||
\ - 1) may_composite = false;\n }\n if (may_composite) return\ | ||
\ false;\n }\n return true;\n }\n} is_prime;\n\nstruct {\n \ | ||
\ // Pollard's rho algorithm: find factor greater than 1\n long long find_factor(long\ | ||
\ long n) {\n assert(n > 1);\n if (n % 2 == 0) return 2;\n \ | ||
\ if (is_prime(n)) return n;\n long long c = 1;\n auto f = [&](__int128\ | ||
\ x) -> long long { return (x * x + c) % n; };\n\n for (int t = 1;; t++)\ | ||
\ {\n for (c = 0; c == 0 or c + 2 == n;) c = rand_int() % n;\n \ | ||
\ long long x0 = t, m = std::max(n >> 3, 1LL), x, ys, y = x0, r = 1, g,\ | ||
\ q = 1;\n do {\n x = y;\n for (int i\ | ||
\ = r; i--;) y = f(y);\n long long k = 0;\n do {\n\ | ||
\ ys = y;\n for (int i = std::min(m, r -\ | ||
\ k); i--;)\n y = f(y), q = __int128(q) * std::abs(x -\ | ||
\ y) % n;\n g = std::__gcd<long long>(q, n);\n \ | ||
\ k += m;\n } while (k < r and g <= 1);\n \ | ||
\ r <<= 1;\n } while (g <= 1);\n if (g == n) {\n \ | ||
\ do {\n ys = f(ys);\n g = std::__gcd(std::abs(x\ | ||
\ - ys), n);\n } while (g <= 1);\n }\n if\ | ||
\ (g != n) return g;\n }\n }\n\n std::vector<long long> operator()(long\ | ||
\ long n) {\n std::vector<long long> ret;\n while (n > 1) {\n \ | ||
\ long long f = find_factor(n);\n if (f < n) {\n \ | ||
\ auto tmp = operator()(f);\n ret.insert(ret.end(), tmp.begin(),\ | ||
\ tmp.end());\n } else\n ret.push_back(n);\n \ | ||
\ n /= f;\n }\n std::sort(ret.begin(), ret.end());\n \ | ||
\ return ret;\n }\n long long euler_phi(long long n) {\n long long\ | ||
\ ret = 1, last = -1;\n for (auto p : this->operator()(n)) ret *= p - (last\ | ||
\ != p), last = p;\n return ret;\n }\n} FactorizeLonglong;\n#line 3\ | ||
\ \"number/test/is_prime.test.cpp\"\n\n#include <iostream>\nusing namespace std;\n\ | ||
\nint main() {\n cin.tie(nullptr);\n ios_base::sync_with_stdio(false);\n\ | ||
\n int Q;\n cin >> Q;\n while (Q--) {\n unsigned long long N;\n\ | ||
\ cin >> N;\n cout << (is_prime(N) ? \"Yes\" : \"No\") << '\\n';\n\ | ||
\ }\n}\n" | ||
code: "#define PROBLEM \"https://judge.yosupo.jp/problem/primality_test\"\n#include\ | ||
\ \"../factorize.hpp\"\n\n#include <iostream>\nusing namespace std;\n\nint main()\ | ||
\ {\n cin.tie(nullptr);\n ios_base::sync_with_stdio(false);\n\n int Q;\n\ | ||
\ cin >> Q;\n while (Q--) {\n unsigned long long N;\n cin\ | ||
\ >> N;\n cout << (is_prime(N) ? \"Yes\" : \"No\") << '\\n';\n }\n}\n" | ||
dependsOn: | ||
- number/factorize.hpp | ||
- random/xorshift.hpp | ||
isVerificationFile: true | ||
path: number/test/is_prime.test.cpp | ||
requiredBy: [] | ||
timestamp: '2023-12-26 22:37:19+09:00' | ||
verificationStatus: TEST_ACCEPTED | ||
verifiedWith: [] | ||
documentation_of: number/test/is_prime.test.cpp | ||
layout: document | ||
redirect_from: | ||
- /verify/number/test/is_prime.test.cpp | ||
- /verify/number/test/is_prime.test.cpp.html | ||
title: number/test/is_prime.test.cpp | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
--- | ||
data: | ||
_extendedDependsOn: | ||
- icon: ':heavy_check_mark:' | ||
path: string/lyndon.hpp | ||
title: "Lyndon words \uFF08Lyndon \u6587\u5B57\u5217\u306B\u95A2\u3059\u308B\u5404\ | ||
\u7A2E\u95A2\u6570\uFF09" | ||
_extendedRequiredBy: [] | ||
_extendedVerifiedWith: [] | ||
_isVerificationFailed: false | ||
_pathExtension: cpp | ||
_verificationStatusIcon: ':heavy_check_mark:' | ||
attributes: | ||
'*NOT_SPECIAL_COMMENTS*': '' | ||
PROBLEM: https://judge.yosupo.jp/problem/lyndon_factorization | ||
links: | ||
- https://judge.yosupo.jp/problem/lyndon_factorization | ||
bundledCode: "#line 1 \"string/test/lyndon.test.cpp\"\n#define PROBLEM \"https://judge.yosupo.jp/problem/lyndon_factorization\"\ | ||
\n#line 2 \"string/lyndon.hpp\"\n#include <algorithm>\n#include <cassert>\n#include\ | ||
\ <functional>\n#include <string>\n#include <tuple>\n#include <utility>\n#include\ | ||
\ <vector>\n\n// CUT begin\n// Lyndon factorization based on Duval's algorithm\n\ | ||
// **NOT VERIFIED YET**\n// Reference:\n// [1] K. T. Chen, R. H. Fox, R. C. Lyndon,\n\ | ||
// \"Free Differential Calculus, IV. The Quotient Groups of the Lower Central\ | ||
\ Series,\"\n// Annals of Mathematics, 68(1), 81-95, 1958.\n// [2] J. P. Duval,\ | ||
\ \"Factorizing words over an ordered alphabet,\"\n// Journal of Algorithms,\ | ||
\ 4(4), 363-381, 1983.\n// - https://cp-algorithms.com/string/lyndon_factorization.html\n\ | ||
// - https://qiita.com/nakashi18/items/66882bd6e0127174267a\ntemplate <typename\ | ||
\ T>\nstd::vector<std::pair<int, int>> lyndon_factorization(const std::vector<T>\ | ||
\ &S) {\n const int N = S.size();\n std::vector<std::pair<int, int>> ret;\n\ | ||
\ for (int l = 0; l < N;) {\n int i = l, j = i + 1;\n while (j\ | ||
\ < N and S[i] <= S[j]) i = (S[i] == S[j] ? i + 1 : l), j++;\n int n =\ | ||
\ (j - l) / (j - i);\n for (int t = 0; t < n; t++) ret.emplace_back(l,\ | ||
\ j - i), l += j - i;\n }\n return ret;\n}\n\nstd::vector<std::pair<int,\ | ||
\ int>> lyndon_factorization(const std::string &s) {\n const int N = int(s.size());\n\ | ||
\ std::vector<int> v(N);\n for (int i = 0; i < N; i++) v[i] = s[i];\n \ | ||
\ return lyndon_factorization<int>(v);\n}\n\n// Compute the longest Lyndon prefix\ | ||
\ for each suffix s[i:N]\n// (Our implementation is $O(N \\cdot (complexity of\ | ||
\ lcplen()))$)\n// Example:\n// - `teletelepathy` -> [1,4,1,2,1,4,1,2,1,4,1,2,1]\n\ | ||
// Reference:\n// [1] H. Bannai et al., \"The \"Runs\" Theorem,\"\n// SIAM\ | ||
\ Journal on Computing, 46(5), 1501-1514, 2017.\ntemplate <typename String, typename\ | ||
\ LCPLENCallable>\nstd::vector<int> longest_lyndon_prefixes(const String &s, const\ | ||
\ LCPLENCallable &lcp) {\n const int N = s.size();\n std::vector<std::pair<int,\ | ||
\ int>> st{{N, N}};\n std::vector<int> ret(N);\n for (int i = N - 1, j =\ | ||
\ i; i >= 0; i--, j = i) {\n while (st.size() > 1) {\n int iv\ | ||
\ = st.back().first, jv = st.back().second;\n int l = lcp.lcplen(i,\ | ||
\ iv);\n if (!(iv + l < N and s[i + l] < s[iv + l])) break;\n \ | ||
\ j = jv;\n st.pop_back();\n }\n st.emplace_back(i,\ | ||
\ j);\n ret[i] = j - i + 1;\n }\n return ret;\n}\n\n// Compute all\ | ||
\ runs in given string\n// Complexity: $O(N \\cdot (complexity of lcplen()))$\ | ||
\ in this implementation\n// (Theoretically $O(N)$ achievable)\n// N = 2e5 ->\ | ||
\ ~120 ms\n// Reference:\n// [1] H. Bannai et al., \"The \"Runs\" Theorem,\"\n\ | ||
// SIAM Journal on Computing, 46(5), 1501-1514, 2017.\ntemplate <typename\ | ||
\ LCPLENCallable, typename String>\nstd::vector<std::tuple<int, int, int>> run_enumerate(String\ | ||
\ s) {\n if (s.empty()) return {};\n LCPLENCallable lcp(s);\n std::reverse(s.begin(),\ | ||
\ s.end());\n LCPLENCallable revlcp(s);\n std::reverse(s.begin(), s.end());\n\ | ||
\ auto t = s;\n auto lo = *std::min_element(s.begin(), s.end()), hi = *std::max_element(s.begin(),\ | ||
\ s.end());\n for (auto &c : t) c = hi - (c - lo);\n auto l1 = longest_lyndon_prefixes(s,\ | ||
\ lcp), l2 = longest_lyndon_prefixes(t, lcp);\n int N = s.size();\n std::vector<std::tuple<int,\ | ||
\ int, int>> ret;\n for (int i = 0; i < N; i++) {\n int j = i + l1[i],\ | ||
\ L = i - revlcp.lcplen(N - i, N - j), R = j + lcp.lcplen(i, j);\n if (R\ | ||
\ - L >= (j - i) * 2) ret.emplace_back(j - i, L, R);\n\n if (l1[i] != l2[i])\ | ||
\ {\n j = i + l2[i], L = i - revlcp.lcplen(N - i, N - j), R = j + lcp.lcplen(i,\ | ||
\ j);\n if (R - L >= (j - i) * 2) ret.emplace_back(j - i, L, R);\n\ | ||
\ }\n }\n std::sort(ret.begin(), ret.end());\n ret.erase(std::unique(ret.begin(),\ | ||
\ ret.end()), ret.end());\n return ret;\n}\n\n// Enumerate Lyndon words up\ | ||
\ to length n in lexical order\n// https://github.com/bqi343/USACO/blob/master/Implementations/content/combinatorial%20(11.2)/DeBruijnSeq.h\n\ | ||
// Example: k=2, n=4 => [[0,],[0,0,0,1,],[0,0,1,],[0,0,1,1,],[0,1,],[0,1,1,],[0,1,1,1,],[1,],]\n\ | ||
// Verified: https://codeforces.com/gym/102001/problem/C / https://codeforces.com/gym/100162/problem/G\n\ | ||
std::vector<std::vector<int>> enumerate_lyndon_words(int k, int n) {\n assert(k\ | ||
\ > 0);\n assert(n > 0);\n std::vector<std::vector<int>> ret;\n std::vector<int>\ | ||
\ aux(n + 1);\n\n std::function<void(int, int)> gen = [&](int t, int p) {\n\ | ||
\ // t: current length\n // p: current min cycle length\n \ | ||
\ if (t == n) {\n std::vector<int> tmp(aux.begin() + 1, aux.begin()\ | ||
\ + p + 1);\n ret.push_back(std::move(tmp));\n } else {\n \ | ||
\ ++t;\n aux[t] = aux[t - p];\n gen(t, p);\n \ | ||
\ while (++aux[t] < k) gen(t, t);\n }\n };\n gen(0, 1);\n\ | ||
\ return ret;\n}\n#line 3 \"string/test/lyndon.test.cpp\"\n\n#include <iostream>\n\ | ||
#line 6 \"string/test/lyndon.test.cpp\"\nusing namespace std;\n\nint main() {\n\ | ||
\ cin.tie(nullptr);\n ios_base::sync_with_stdio(false);\n\n string S;\n\ | ||
\ cin >> S;\n auto ret = lyndon_factorization(S);\n for (auto [l, len]\ | ||
\ : ret) cout << l << ' ';\n cout << S.size() << '\\n';\n}\n" | ||
code: "#define PROBLEM \"https://judge.yosupo.jp/problem/lyndon_factorization\"\n\ | ||
#include \"../lyndon.hpp\"\n\n#include <iostream>\n#include <string>\nusing namespace\ | ||
\ std;\n\nint main() {\n cin.tie(nullptr);\n ios_base::sync_with_stdio(false);\n\ | ||
\n string S;\n cin >> S;\n auto ret = lyndon_factorization(S);\n for\ | ||
\ (auto [l, len] : ret) cout << l << ' ';\n cout << S.size() << '\\n';\n}\n" | ||
dependsOn: | ||
- string/lyndon.hpp | ||
isVerificationFile: true | ||
path: string/test/lyndon.test.cpp | ||
requiredBy: [] | ||
timestamp: '2023-12-26 22:37:19+09:00' | ||
verificationStatus: TEST_ACCEPTED | ||
verifiedWith: [] | ||
documentation_of: string/test/lyndon.test.cpp | ||
layout: document | ||
redirect_from: | ||
- /verify/string/test/lyndon.test.cpp | ||
- /verify/string/test/lyndon.test.cpp.html | ||
title: string/test/lyndon.test.cpp | ||
--- |