This documentation is automatically generated by competitive-verifier/competitive-verifier
#include "math/number-theory/EulersPhiFunction.hpp"
todo
todo
#include "Factorize.hpp"
long long Eulers_phi_function(long long n) {
__uint128_t upper = n;
__uint128_t lower = 1;
for (const long long p : factorize(n, true)) {
upper *= (p - 1);
lower *= p;
}
return upper / lower;
}
#line 1 "math/number-theory/PrimalityTest.hpp"
__int128_t mod_pow(__int128_t a, long long n, long long m) {
__int128_t res = 1;
a %= m;
while (n) {
if (n & 1) res = (res * a) % m;
a = (a * a) % m;
n >>= 1;
}
return res;
}
constexpr long long MR[] = {2, 7, 61};
constexpr long long MRl[] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
bool Miller_Rabin(long long n) {
long long s = 0;
long long d = n - 1;
while ((d & 1) == 0) {
s++;
d >>= 1;
}
for (int i = 0; i < 3; i++) {
if (n <= MR[i]) return true;
__int128_t x = mod_pow(MR[i], d, n);
if (x != 1) {
bool ok = false;
for (int t = 0; t < s; t++) {
if (x == n - 1) {
ok = true;
break;
}
x = x * x % n;
}
if (!ok) return false;
}
}
return true;
}
bool Miller_Rabinl(long long n) {
long long s = 0;
long long d = n - 1;
while ((d & 1) == 0) {
s++;
d >>= 1;
}
for (int i = 0; i < 7; i++) {
if (n <= MRl[i]) return true;
__int128_t x = mod_pow(MRl[i], d, n);
if (x != 1) {
bool ok = false;
for (int t = 0; t < s; t++) {
if (x == n - 1) {
ok = true;
break;
}
x = x * x % n;
}
if (!ok) return false;
}
}
return true;
}
bool brute_force(long long n) {
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
bool is_prime(long long n) {
if (n == 2) return true;
if ((n & 1) == 0 or n < 2) return false;
if (n < 1000) return brute_force(n);
if (n < 4759123141LL) {
return Miller_Rabin(n);
}
return Miller_Rabinl(n);
}
#line 2 "math/number-theory/Factorize.hpp"
long long find_prime_factor(long long n) {
if ((n & 1) == 0) return 2;
long long m = int64_t(powl(n, 0.125)) + 1;
for (int i = 1; i < n; i++) {
long long y = 0;
long long g = 1;
long long q = 1;
long long r = 1;
long long k = 0;
long long ys = 0;
long long x = 0;
while (g == 1) {
x = y;
while (k < 3ll * r / 4) {
y = (__int128_t(y) * y + i) % n;
k++;
}
while (k < r and g == 1) {
ys = y;
for (int j = 0; j < min(m, r - k); j++) {
y = (__int128_t(y) * y + i) % n;
q = (__int128_t(q) * abs(x - y)) % n;
}
g = gcd(q, n);
k += m;
}
k = r;
r <<= 1;
}
if (g == n) {
g = 1;
y = ys;
while (g == 1) {
y = (__int128_t(y) * y + i) % n;
g = gcd(abs(x - y), n);
}
}
if (g == n) continue;
if (is_prime(g)) return g;
if (is_prime(n / g)) return n / g;
return find_prime_factor(g);
}
return -1;
}
vector<long long> factorize(long long n, bool set = false) {
vector<long long> res;
while (!is_prime(n) and n > 1) {
long long p = find_prime_factor(n);
if (set) res.emplace_back(p);
while (n % p == 0) {
n /= p;
if (!set) res.emplace_back(p);
}
}
if (n > 1) {
res.emplace_back(n);
}
sort(res.begin(), res.end());
return res;
}
#line 2 "math/number-theory/EulersPhiFunction.hpp"
long long Eulers_phi_function(long long n) {
__uint128_t upper = n;
__uint128_t lower = 1;
for (const long long p : factorize(n, true)) {
upper *= (p - 1);
lower *= p;
}
return upper / lower;
}