先介绍基本概念:
1.同余
数论中的重要概念。给定一个正整数m,如果两个整数a和b满足a-b能被m整除,即m|(a-b),那么就称整数a与b对模m同余,记作a≡b(mod m)。对模m同余是整数的一个等价关系。
2.线性筛素数法
普通筛素数法很简单:对于不超过n的每个非负整数p,删除2p,3p,4p.....当处理完所有素数后,还没有被删除的就是素数。如果用vis[i]表示i已经被删除,那么代码可以写成这样:
memset(vis,0,sizeof(vis));
for (int i = 2; i <= n ;i++)
for (int j = 2*i,j<=n; j +=i)
vis[j]=1;
很好证明,这种筛选素数的方法时间复杂度为O(n*logn)。不知道你发现没有,这种算法里面一个元素被删了好多次,有没有办法优化成线性时间?当然可以。
我们对每个素数p考虑所有i ,如果i 的最小素因子>=p 那么可以断定 i*p 不可能是素数。用代码实现就是:
memset(Prime,0,sizeof(Prime));
memset(IsPrime,1,sizeof(IsPrime));
for (int i=2;i<=n;i++){
if (IsPrime[i])
Prime[num++] = i;
for (int j=1;j<num && i*Prime[j]<=n;j++){
IsPrime[i*Prime[j]] = 0;
if (i%Prime[j] == 0) break;
}
}
3、欧拉函数
在数论,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's totient function、φ函数、欧拉商数等。
例如φ(8)=4,因为1,3,5,7均和8互质。
例如φ(8)=4,因为1,3,5,7均和8互质。
求从1到n-1与n互质的数的个数,代码如下
int eular(int n)
{
int ret = 1,i;
for (i = 2;i * i <= n;i++)
if (n % i == 0)
{
n /= i;
ret *= (i - 1);
while (n % i == 0)
{
n /= i;
ret *= i;
}
}
if (n > 1)
ret *= (n - 1);
return ret;
}