voidinit(int n)// Pretreating n phi[]s { phi[1] = 1; for (int i = 2; i <= n; i++) { if (!vis[i]) { primes[++cnt] = i; phi[i] = i - 1; } for (int j = 1; j <= cnt && primes[j] * i <= n; j++) { vis[primes[j] * i] = true; if (i % primes[j] == 0) { phi[primes[j] * i] = phi[i] * primes[j]; break; } phi[primes[j] * i] = phi[i] * (primes[j] - 1); } } } intPhi(int x)//Calculating one phi { int res = x; for (int i = 2; i * i <= x; i++) if (x % i == 0) { res = res / i * (i - 1); while (x % i == 0) x /= i; } if (x > 1) res = res / x * (x - 1); return res; } intbinpow(int x, int k, int mod) { int res = 1 % mod, b = x % mod; while (k) { if (k & 1) res = res * b % mod; b = b * b % mod; k >>= 1; } return res; } intinv(int a, int b) { returnbinpow(a, phi[b] - 1, b); }
Fermat’s Little Theorem
Used when $ b \in Primes$ .
Complexity: $O(\log b)$ .
查看代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
intbinpow(int x, int k, int mod) { int res = 1 % mod, b = x % mod; while (k) { if (k & 1) res = res * b % mod; b = b * b % mod; k >>= 1; } return res; } intinv(int a, int b) { returnbinpow(a, b - 2, b); }
Extended Euclidean Algorithm
Complexity: $O(\log a + \log b)$ .
查看代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
voidexgcd(int a, int b, int& x, int& y) { if (!b) { x = 1, y = 0; return; } exgcd(b, a % b, y, x); y -= a / b * x; } intinv(int a, int b) { int x, y; exgcd(a, b, x, y); return (x % b + b) % b; }