数论之素数,包括eratosthenes算法,欧拉函数
来源:互联网 发布:网络悬疑剧两小无猜 编辑:程序博客网 时间:2024/05/02 00:34
一,素数
素数又称质数,有无限个。除了1和它本身以外不再有其他的除数整除。
算术基本定理:每个大于1的自然数均可写为质数的积,而且这些素因子按大小排列之后,写法仅有一种方式。
例如:6936=2^3*3*17^2,1200=2^4*3*5^2。
二,质因数的分解
概念:把一个合数用素因数相乘的形式表示出来,叫做质因数分解。(注意:由于任何一个合数n至多会有一个大于根号n的因子)
一般我们用短除法分解素因数,算法步骤如下:
1.先用一个能整除这个合数的素数(通常从最小的开始)去除。
2.得出的商如果是合数,再按照上面的方法继续除下去,直到得出的商是素数为止。
3.然后把各个除数和最后的商按从小到大的顺序写成连乘的形式。
代码如下:cnt=0; //cnt表示素因子的个数
for(int i=2;i*i<=n;i++)//由于任何一个合数至多或有一个大于根号n的因子
{
if(n%i==0)
{
++cnt;
p[cnt]=i;//p数组存的是素因子
num[cnt]=0;//存的是每个素因子的指数
while(n%i==0)
{
++num[cnt];
n/=i;
}//while循环的目的是每次历经一个i,n都会进行更新,或者是有多个i,n也会进行更新
}
}
if(n>1)
{
++cnt;
p[cnt]=n;
num[cnt]=1;
}需要if循环的原因也是因为由于任何一个合数至多或有一个大于根号n的因子(例如n=10)
三,素数的测试
1,一般的思路
bool divisibiity_test(int n)
{
for (int i=2; i<n; i++)
if (n % i == 0)
return false; // 不是质数
return true; // 是质数
}
2,改进的方法
bool divisibiity_test(int n)
{
//一个数至少有一个比sprt(n)小的质因数。
for (int i=2; i<=sqrt(n); i++)
if (n % i == 0)
return false;
return true;
}
时间复杂度:O(sqrtN)
四,Eratosthenes筛法
代码如下:
1,
bool prime[20000000];
void eratosthenes()
{
memset(prime,1,sizeof(prime));
prime[0] = 0; prime[1] = 0; // 0 和 1 不是质数
for (int i=2; i<20000000; i++)
if (prime[i]==1) // 删掉质数i的倍数
for (int j=i+i; j<20000000; j+=i)
prime[j] = 0;
}
2,优化的如下:(优化的原因:删掉质数 i 的倍数时,早已删掉1 倍~ i-1 倍之间的合数了,所以直接从i倍开始删除)。
void eratosthenes(){
memset(prime,1,sizeof(prime));
prime[0] = 0;prime[1] = 0;
for (int i=2; i<20000000; i++)
if (prime[i]==1)
//删掉i的倍数从i倍开始。
for (int j=i*i; j<20000000; j+=i)
prime[j] = 0;
}
五,欧拉函数
1.定理:
对正整数n,欧拉函数φ(phi)指是小于n的所有数中与之互质的个数(包含1)。如φ(8)=4,因为1,3,5,7均和8互质
2.表达形式:n=p1^a1*p2^a2....pk^ak(p1,p2...pk是素数)
3,计算公式:φ(n)=n*(1-1/p1)*(1-1/p2)*......*(1-1/pk)
例如:φ(8)=4有1,3,5,7,8=2^3, φ(8)=8*(1-1/2)=4.
φ(10)=4有1,3,7,9 ,10=2*5,φ(10)=10*(1-1/2)*(1-1/5)=4.
4,性质:
a)当p为质数时, φ(p) = p – 1。
证明:因为小于本身的数都与该数互质,但是注意φ(1)=1.
b)对于互质的正整数a和n,有a^φ(n) ≡ 1 (mod n) (mod n的意思是两边同时%n).
c)费马小定理:若正整数a 与素数p 互质,则有a^(p - 1)≡1 mod p。
证明:由于性质a可知当p为质数,φ(p) = p -1,代入性质b即可证明。
d)当n为奇数时φ(2n)=φ(n).
e)当n和m互质时,φ(n*m)=φ(n)*φ(m).
f)若n=p^k(p为质数),φ(n)=p^k-p^(k-1).
证明:因为除了p的倍数外,其他数都跟n互质。
朴素算法实现:
1.根据公式1:n=p1^k1*p2^k2*…*pr^kr和公式2:φ(n)=n* (1-1/p1) *…* (1-1/pr)。
2.可将公式2可拆成n* (1-1/p1)=n-n/p1计算。
代码实现:
int euler(int n)
{
int i,ans=n;
for(i=2; i*i<=n; i++)
if(n%i==0)
{
ans=ans-ans/i;
do
n/=i;//把该素因子全部约掉
while(n%i==0);
}
if(n>1)
ans=ans-ans/n;
return ans;
}
例题:
1286.有多少素数
Total Submission(s): 319 Accepted Submission(s): 44
Description
Input
Output
Sample Input
32 3 4
Sample Output
2
(已经AC过的代码)
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int IsPrimeNumber(int n)
{
if (n==2)
{
return true;
}
if (n%2==0)
{
return false;
}
int sqrtn=(int)sqrt((double)n);
bool flag=true;
for (int i=3; i<=sqrtn; i+=2)
{
if (n%i==0)
{
flag=false;
}
}
return flag;
}
int main()
{
int m,n,x;
while(scanf("%d",&m)!=EOF)
{
int sum=0;
for(int k=0; k<m; k++)
{
scanf("%d",&n);
x=IsPrimeNumber(n);
if(x)
sum++;
}
cout<<sum<<'\n';
}
return 0;
}
- 数论之素数,包括eratosthenes算法,欧拉函数
- 数论之 素因子分解,素数筛选法,欧拉函数和扩展欧几里得算法 (整理)
- 数论之欧拉函数
- 数论之欧拉函数
- 欧拉函数 算法摘记 数论
- 【数论】【素数】素数相关基础——欧拉函数与欧拉定理
- ACM常用数论之欧拉函数
- 数论欧拉函数
- 欧拉函数(数论)
- 数论-欧拉函数
- 欧拉函数---数论
- 数论模版-欧拉函数、莫比乌斯函数和素数
- uva10820(数论 +欧拉函数)
- 欧拉函数(数论)
- 欧拉函数相关数论
- HDU 1695 GCD (数论-整数和素数,欧拉函数,组合数学-容斥原理)
- 【数论】gcd|扩展gcd|素数筛法|快速幂|欧拉函数(各种模板)
- ACM第一课---数论之欧拉函数
- 我的第一步
- 【PAT】1028. List Sorting
- 微信小程序中设置全局变量
- 递归—二分查找
- 【WPF】ListBox使用UserContrl作为子控件
- 数论之素数,包括eratosthenes算法,欧拉函数
- 洛谷 P1135 奇怪的电梯
- esp-pos打印图片和二维码
- R语言实战笔记--第十四章 主成分和因子分析
- TextView使用SpannableString设置某部分文本的各种属性(点击、颜色、下划线...)
- WinC++简易的web服务器
- 深入理解include预编译原理
- 4、按键控制
- 修改Visual Studio 2015 Community默认程序文件编码为GB2312暨解决老版本显示乱码或汉字字符报错的方法