标签:约数 数论 质数 笔记 int primes 质因数 复杂度
质数
1、质数的判定:
试除法判定质数
//朴素写法,时间复杂度O(n)
bool isprime(int n){
if(n<2) return false;
for(int i = 2; i < n; ++ i)
if(n % i == 0)
return false;
return true;
}
我们发现对于任何一个能整除n的数d,则n / d也能整除n
所以我们只需要枚举到n / d即可
//优化后代码,时间复杂度是O(根号n)
bool isprime(int n){
if(n<2) return false;
for(int i = 2; i <= n / i; ++ i)
if(n % i == 0)
return false;
return true;
}
2、分解质因数
//试除法分解质因数
void divide(int n){
for(int i = 2; i <= n; ++ i)
if(n % i == 0){
int s = 0;
while(n % i == 0){
n /= i;
s ++;
}
cout << i << ' ' << s << endl;
}
puts("");
}
我们发现n中至多有一个质因数大于根号n,假设有两个质因数x、y大于根号n,那么x * y就大于n不符合条件,所以我们将这个大于根号n的质因数特判一下即可
void divide(int n){
for(int i = 2; i <= n / i; ++ i)
if(n % i == 0){
int s = 0;
while(n % i == 0){
n /= i;
s ++;
}
cout << i << ' ' << s << endl;
}
if(n > 1) cout << n << ' ' << 1 << endl;
puts("");
}
筛法求质数
朴素筛法:从小到大枚举,未被标记则加入质数表内,然后把它的倍数筛除
//时间复杂度O(nlogn)
void get_primes(int n)
{
for(int i = 2; i <= n; ++ i){
if(!st[i]) primes[cnt ++] = i;
for(int j = i + i; j <= n; j += i)
st[j] = true;
}
}
我们发现有很多冗余,有些数被筛除了很多次,观察质数和约数的性质,我们发现每一个约数都是质数的倍数,所以我们只用筛除质数的倍数即可
//时间复杂度为O(nloglogn)
void get_primes(int n)
{
for(int i = 2; i <= n; ++ i){
if(!st[i]){
primes[cnt ++] = i;
for(int j = i + i; j <= n; j += i)
st[j] = true;
}
}
}
线性筛法:每次只用一个数的最小质因数将这个数筛除
//时间复杂度O(n)
void get_primes(int n)
{
for(int i = 2; i <= n; ++ i){
if(!st[i]) primes[cnt ++] = i;
for(int j = 0; primes[j] <= n / i; ++ j){
st[primes[j] * i] = true;
if(i % primes[j] == 0) break;
}
}
}
约数
试除法求约数
和试除法判定质数相同,我们发现对于任何一个能整除n的数d,则n / d也能整除n,所以我们只用枚举到n / d,用d算出来另一个约数n / d即可
//时间复杂度O(根号n + nlogn),排序时间复杂度O(nlogn)
vector<int> get_divisors(int n){
vector<int> res;
for(int i=1; i<=n/i; ++i)
if(n%i == 0){
res.push_back(i);
if(i != n/i) res.push_back(n/i);
}
sort(res.begin(), res.end());
return res;
}
约数个数与约数之和
最大公约数
欧几里德算法
int gcd(int a, int b)
{
return b ? gcd(b, a%b) : a;
}
欧拉函数
标签:约数,数论,质数,笔记,int,primes,质因数,复杂度 来源: https://blog.csdn.net/qq_50702668/article/details/115125964
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。