This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub kmyk/competitive-programming-library
#include "number/miller-rabin.hpp"
#pragma once #include <cassert> #include <random> #include "../utils/macros.hpp" #include "../modulus/modpow.hpp" /** * @brief miller-rabin primality test * @note $O(k \log n)$ */ template <class RandomEngine> bool is_prime(int64_t n, int iteration, RandomEngine& gen) { assert (0 <= n); if (n == 2) return true; if (n == 1 or n % 2 == 0) return false; const int64_t d = (n - 1) >> __builtin_ctzll(n - 1); // remove trailing zeros std::uniform_int_distribution<int64_t> dist(1, n - 2); // [l, r] REP (dummy, iteration) { int64_t a = dist(gen); int64_t t = d; int64_t y = modpow(a, t, n); while (t != n - 1 and y != 1 and y != n - 1) { y = y * y % n; t *= 2; } if (y != n - 1 and t % 2 == 0) return false; } return true; } bool is_prime(int64_t n) { static std::default_random_engine gen = std::default_random_engine(std::random_device()()); return is_prime(n, 20, gen); }
#line 2 "number/miller-rabin.hpp" #include <cassert> #include <random> #line 2 "utils/macros.hpp" #define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i)) #define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i)) #define REP_R(i, n) for (int i = (int)(n) - 1; (i) >= 0; -- (i)) #define REP3R(i, m, n) for (int i = (int)(n) - 1; (i) >= (int)(m); -- (i)) #define ALL(x) std::begin(x), std::end(x) #line 3 "modulus/modpow.hpp" #include <cstdint> inline int32_t modpow(uint_fast64_t x, uint64_t k, int32_t MOD) { assert (/* 0 <= x and */ x < (uint_fast64_t)MOD); uint_fast64_t y = 1; for (; k; k >>= 1) { if (k & 1) (y *= x) %= MOD; (x *= x) %= MOD; } assert (/* 0 <= y and */ y < (uint_fast64_t)MOD); return y; } #line 6 "number/miller-rabin.hpp" /** * @brief miller-rabin primality test * @note $O(k \log n)$ */ template <class RandomEngine> bool is_prime(int64_t n, int iteration, RandomEngine& gen) { assert (0 <= n); if (n == 2) return true; if (n == 1 or n % 2 == 0) return false; const int64_t d = (n - 1) >> __builtin_ctzll(n - 1); // remove trailing zeros std::uniform_int_distribution<int64_t> dist(1, n - 2); // [l, r] REP (dummy, iteration) { int64_t a = dist(gen); int64_t t = d; int64_t y = modpow(a, t, n); while (t != n - 1 and y != 1 and y != n - 1) { y = y * y % n; t *= 2; } if (y != n - 1 and t % 2 == 0) return false; } return true; } bool is_prime(int64_t n) { static std::default_random_engine gen = std::default_random_engine(std::random_device()()); return is_prime(n, 20, gen); }