欧拉函数
- f(n) 1-n中与n互质的数的个数
求法1–公式求 O(n sqrt(n))
- 先分解质因数 N = p1^a1 * p2^a2 * … *pk^ak
- f(n) = N[1 - (1/p1 )][1-(1/p2 )]…[1-(1/pn )]
原理
- 从1~N中去掉p1,p2,…,pk的所有倍数
- 加上所有pi*pj的倍数(被减了两次)
- 减去所有pi* pj *pk的倍数
- 以此类推偶加奇减(容斥原理)
代码
int res = a; for(int i = 2; i <= a / i; i ++) if(a % i == 0) { res = res / i * (i - 1);//等价于res*(1- 1/n) while(a % i == 0) a/= i; } if(a > 1) res = res / a * (a - 1); cout << res << endl;
求法2–筛法
- 适用于求1~n每个数的欧拉
- 利用了线性筛法求质数
- 代码
phi[1] = 1;//1的特殊记 for(int i = 2; i <= n; i ++) { if(!st[i]) { primes[cnt ++] = i; phi[i] = i - 1;//质数n的欧拉为1~(n-1) } for(int j = 0; primes[j] <= n / i; j ++) { st[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);//phi[i]*primes[j]*(1- 1/primrs[j]) } }
欧拉定理
- 若a与n互质 a^f(n) mod n = 1;
- 当n为质数时a^(p-1)同余1
快速幂
- 快速求出a^k mod p的结果 O(logk)
原理
- 反复平方法
- 先预处理出a(20) mod p, a(21) mod p …a(2logk) mod p
- 把k换成二进制
int qmi(int a, int k, int p)
{
int res = 1;
while(k)
{
if(k &1) res = (LL)res * a % p;
k >>= 1;
a = (LL)a * a % p;
}
return res;
}