数论总结
内容:欧拉函数,欧拉定理,费马小定理,中国剩余定理,欧几里得定理,扩展欧几里得定理,逆元,线性筛、卡特兰数、快速幂、快速乘、矩阵乘法。
欧拉函数:A={ x | 1 < =x < n, gcd(x,n) = 1} 特殊的质数p的欧拉函数为p-1,
p的a次方的欧拉函数为p的a次方减p的a-1次方,可以在线性筛的过程中求出欧拉函数复杂度O(n)
代码为:
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 1000005;
int isnot[N], prime[N], n, ptot, phi[N];
void line_oula() {
isnot[1] = 1;
phi[1] = 1;
for ( int i = 2; i <= n; i++ ) {
if ( !isnot[i] ) prime[ptot++] = i, phi[i] = i - 1;
for ( int t = 0; t < ptot; t++ ) {
int j = prime[t] * i;
if ( j > n ) break;
isnot[j] = true;
phi[j] = phi[prime[t]] * phi[i];//phi[nm]=phi[n]*phi[m] gcd(n,m) = 1
if ( i % prime[t] == 0 ) {
phi[j] = prime[t] * phi[i];//phi[p*i]=phi[p*p*k]=phi[k*p*p]=phi[k]*phi[p]*p=p*phi[i]
break;
}
}
}
}
int main() {
scanf( "%d", &n );
line_oula();
for ( int i = 1; i <= n; i++ )
cout << phi[i] << endl;
}
在求递推公式的时候分两种情况详见代码。
欧拉定理: 当gcd(a,n)=1时,
此定理的一个推论为费马小定理:当n取质数时
同时扩展而来可得逆元的多种求法:
逆元:ax≡1 (mod p),且gcd(a,p)=1(a与p互质),则称a关于模p的乘法逆元为x。
1、 用费马小定理:两边同乘a的逆元可得a的逆元为a的p-2次方mod p,
注意:此算法需要p为质数!一般用快速幂直接求得,此求法为欧拉定理的特殊化,当p不为质数时用欧拉定理即可两边同乘a的逆元,但需多算一个欧拉函数。
代码:略。
2、 用扩展欧几里得定理:设ax 除以p为t余数为1
则可得pt+1=ax化为方程为pt-ax=1方程可以用扩展欧几里得求出,
扩展欧几里得:d = gcd(a,b)可以表示为 d = ax + by
代码:略。
注意:此算法当p无需为质数
3、 用递推公式求得:令p = aq + r mod(p) 两边同乘a的逆元和r的逆元可得
a的逆元为负的r的逆元乘q mod (p)
代码为:
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 1000005;
int inva[N], n, p;
void inverse() {
inva[1] = 1;
for ( int i = 2; i <= n; i++ )
inva[i] = ( -( p / i * inva[p%i] ) % p + p ) % p;
}
int main() {
scanf( "%d%d", &n, &p );
inverse();
for ( int i = 1; i <= n ; i++ )
cout << inva[i] << endl;
return 0;
}
注意:此算法p必须为质数!!!
卡特兰数:递推公式h[1] = 1,h[n] = h[n-1] *(4*n-2)/(n+1)
快速幂
代码:
long long fpow( long long a, long long b )
{
long long ans = 1;
for ( ; b; b >>= 1, a = ( a%MOD * a%MOD ) % MOD )
if ( b & 1 ) ans = (ans%MOD * a % MOD)%MOD;
return ans;
}
快速乘:
代码:
long long fcheng( long long a, long long b )
{
long long ans = 0;
for ( ; b; b >>= 1,a = ( a%MOD + a%MOD ) % MOD )
if ( b & 1 ) ans = (ans%MOD + a%MOD) % MOD;
return ans;
}