链接:http://oj.hzjingma.com/p/7809?view=classic
来源:竞码编程

题目描述
  求所有 2 2 2 到 n n n 的整数中,因数个数第 k k k 少的数因数个数是多少。
输入描述
  第一行两个正整数 n n n , k k k 即题目描述中的 n n n , k k k 。
输出描述
  输出仅一行,即因数个数第 k k k 少的数因数个数。
输入
  10 5
输出
  3

  解法一:直接暴力求解, s q r t ( n ) sqrt(n) sqrt(n) 判断因子个数。复杂度 O ( n √ n ) O(n√n) O(n√n),对于此题目来说会 T L E TLE TLE 。

#include<bits/stdc++.h>
using namespace std;typedef long long ll;
const int maxn = 2e7 + 10;
ll cnt[maxn];
set<ll>s;ll cal(int x) {ll cnt1 = 2;if(x == 1)return 1;for(ll i = 2; i * i <= x; i++) {if(x % i == 0) {if(i * i == x)cnt1++;elsecnt1 += 2;}}return cnt1;
}int main() {int n, k;scanf("%d%d", &n, &k);for(int i = 2; i <= n; i++)cnt[i] = cal(i);sort(cnt + 1, cnt + n + 1);//for(int i=2;i<=n;i++) cout<<cnt[i]<<" "<<endl;printf("%lld\n", cnt[k + 1]);/*s.insert(cal(i));int cnt2=0;for(set<ll>::iterator it=s.begin();it!=s.end();it++) cnt[cnt2++]=*it;sort(cnt,cnt+cnt2);*/return 0;
}

  解法二:用类似于埃式筛法的方法从 2 − n 2-n 2−n 此把每个数的倍数因子 + + ++ ++, s o r t sort sort 之后直接输出结果。复杂度: O ( n l o g n ) O(nlogn) O(nlogn),这个 o j oj oj 能跑过去 1 e 8 1e8 1e8 的代码。

#include<bits/stdc++.h>
using namespace std;typedef long long ll;
const int maxn = 2e7 + 10;
int cnt[maxn];inline int read() {int x = 0, neg = 1;char op = getchar();while (!isdigit(op)) {if (op == '-')neg = -1;op = getchar();}while (isdigit(op)) {x = 10 * x + op - '0';op = getchar();}return neg * x;
}
inline void print(int x) {if (x < 0) {putchar('-');x = -x;}if (x >= 10)print(x / 10);putchar(x % 10 + '0');
}int main() {int n, k;n = read();k = read();if(n >= maxn)puts("2");else {for(int i = 2; i <= n; i++) {cnt[i] += 2;for(int j = 2 * i; j <= n; j += i)cnt[j]++;}sort(cnt + 1, cnt + n + 1);print(cnt[k + 1]);}return 0;
}

  解法三:我们可以知道,对于每一个数 n n n 都可以分解成如下的式子
   n = p 1 k 1 × p 2 k 2 × p 3 k 3 × ⋅ ⋅ ⋅ ⋅ × p x k x × ⋅ ⋅ ⋅ ⋅ n = p_{1}^{k_{1}} × p_{2}^{k_{2}} ×p_{3}^{k_{3}} × ···· × p_{x}^{k_{x}} × ···· n=p1k1​​×p2k2​​×p3k3​​×⋅⋅⋅⋅×pxkx​​×⋅⋅⋅⋅
   p p p 表示质因子, k k k 表示质因子的个数
  那个就有 n n n 的因子个数 c n t [ n ] = ( k 1 + 1 ) × ( k 2 + 1 ) × ( k 3 + 1 ) × ⋅ ⋅ ⋅ ⋅ × ( k 4 + 1 ) × ⋅ ⋅ ⋅ ⋅ cnt[n] = (k1+1) × (k2+1) × (k3+1) × ···· × (k4+1) × ···· cnt[n]=(k1+1)×(k2+1)×(k3+1)×⋅⋅⋅⋅×(k4+1)×⋅⋅⋅⋅
  在欧拉筛的过程中,当 i i i 为素数的时候, c n t [ i ] = 2 cnt[i] = 2 cnt[i]=2(素数只有两个因子),此时我们在使用一个数组 t i m e s times times 来表示 i i i 的最小质因子的个数,此时 t i m e s [ i ] = 1 times[i] = 1 times[i]=1 ,这个素数当前的质因子只有 1 1 1 个。
当 i % p r i m e [ j ] = = 0 i \% prime[j] == 0 i%prime[j]==0 的时候:
   i = p 1 k 1 × p 2 k 2 × p 3 k 3 i = p_{1}^{k_{1}} × p_{2}^{k_{2}} ×p_{3}^{k_{3}} i=p1k1​​×p2k2​​×p3k3​​
  那么 i ∗ p r i m e [ j ] i * prime[j] i∗prime[j] 就是 i i i 中的最小质因子的个数加一
  此时就有 t i m e s [ i ∗ p r i m e [ j ] ] = t i m e s [ i ] + 1 times[i * prime[j]] = times[i] + 1 times[i∗prime[j]]=times[i]+1 , i i i 的 最小质因子数加一就是 i ∗ p r i m e [ j ] i * prime[j] i∗prime[j] 的最小质因子的个数,此时这个数的因子个数就会随之改变,就变成了 c n t [ i ∗ p r i m e [ j ] ] = ( k 1 + 1 + 1 ) × ( k 2 + 1 ) × ( k 3 + 1 ) × ⋅ ⋅ ⋅ ⋅ × ( k 4 + 1 ) × ⋅ ⋅ ⋅ ⋅ cnt[i*prime[j]] = (k1+1+1) × (k2+1) × (k3+1) × ···· × (k4+1) × ···· cnt[i∗prime[j]]=(k1+1+1)×(k2+1)×(k3+1)×⋅⋅⋅⋅×(k4+1)×⋅⋅⋅⋅, k 1 + 1 k1+1 k1+1 是原本 i i i 的最小质因子的个数, k 1 + 1 + 1 k1+1+1 k1+1+1 则是现在这个数的最小质因子的个数,所以就可以得到 c n t [ i ∗ p r i m e [ j ] ] = c n t [ i ] / ( t i m e s [ i ] + 1 ) ∗ ( t i m e s [ i ∗ p r i m e [ j ] ] + 1 ) cnt[i*prime[j]] = cnt[i]/(times[i]+1)*(times[i*prime[j]]+1) cnt[i∗prime[j]]=cnt[i]/(times[i]+1)∗(times[i∗prime[j]]+1) 加一表示 1 1 1 也是这个数的因子,然后退出这层循环,因为后面的数会在遍历其他数字的时候被筛去。
当 i % p r i m e [ j ] ! = 0 i \% prime[j] != 0 i%prime[j]!=0 的时候:
  说明 i i i 中没有这个这个素数,那么 i ∗ p r i m e [ j ] i*prime[j] i∗prime[j] 就多了一种素数,这个素数出现的次数 t i m e s [ i ∗ p r i m e [ i ] ] = 1 times[i*prime[i]] = 1 times[i∗prime[i]]=1 ,因子个数 c n t [ i ∗ p r i m e [ i ] ] = c n t [ i ] ∗ ( t i m e s [ i ∗ p r i m e [ i ] ] + 1 ) = c n t [ i ] ∗ 2 cnt[i*prime[i]] = cnt[i] * (times[i*prime[i]] + 1) = cnt[i] * 2 cnt[i∗prime[i]]=cnt[i]∗(times[i∗prime[i]]+1)=cnt[i]∗2。
复杂度: O ( n ) O(n) O(n)

#include<bits/stdc++.h>
using namespace std;const int maxn = 2e7 + 10;
int cnt[maxn] = {0, 1}, times[maxn], prime[maxn], num1[maxn]; //最小质因子出现次数
bool is_prime[maxn];inline int read() {int x = 0, neg = 1;char op = getchar();while (!isdigit(op)) {if (op == '-')neg = -1;op = getchar();}while (isdigit(op)) {x = 10 * x + op - '0';op = getchar();}return neg * x;
}
inline void print(int x) {if (x < 0) {putchar('-');x = -x;}if (x >= 10)print(x / 10);putchar(x % 10 + '0');
}void solve() {for(int i = 2; i <= maxn; i++)is_prime[i] = true;is_prime[0] = is_prime[1] = false;int num = 0;for(int i = 2; i <= maxn; i++) {if(is_prime[i]) {cnt[i] = 2;times[i] = 1;prime[num++] = i;}for(int j = 0; j < num; j++) {if(i * prime[j] > maxn)break;is_prime[i * prime[j]] = false;if(i % prime[j] == 0) { //当前素数是最小质因子times[i * prime[j]] = times[i] + 1;cnt[i * prime[j]] = cnt[i] / (times[i] + 1) * (times[i * prime[j]] + 1);break;}times[i * prime[j]] = 1;cnt[i * prime[j]] = cnt[i] * 2;}}
}int main() {solve();int n, k;n = read();k = read();if(n >= maxn)puts("2");else {//for(int i=2;i<=n;i++) cout<<cnt[i]<<" "; cout<<endl;for(int i = 2; i <= n; i++)num1[cnt[i]]++;//for(int i=2;i<=n;i++) cout<<num1[i]<<" "; cout<<endl;int cnt1 = 0;for(int i = 2; i <= n; i++) {while(num1[i]--)++cnt1;if(cnt1 >= k) {print(i);break;}}}return 0;
}

7809 - 试题J:因数个数 25'(欧拉筛法求因子个数)相关推荐

  1. 质数c语言欧拉筛选,Python|欧拉筛法求质数

    欢迎点击「算法与编程之美」↑关注我们! 本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章. 问题描述 我们知道第一个质数是 2.第二个质数是 3.第三个质 ...

  2. 欧拉函数求互质数个数

    求解与n(1-n-1)互质的质因子的个数 解析: 定义:对于正整数n,φ(n)是小于或等于n的正整数中,与n互质的数的数目. 例如:φ(8)=4,因为1,3,5,7均和8互质. 性质:1.若p是质数, ...

  3. 欧拉函数求一个数倒数的循环节长度

    首先,费马小定理a与p互素,则a^(p-1)≡1(mod p)  对于一个素数p,取a=10,那么10^(p-1)≡1(mod p)  如果找到一个正整数e使得10^e/p-1/p为整数,那么e就是1 ...

  4. python编写一个欧拉筛法求素数的小程序

    n=eval(input()) #代码开始 def ouLaShai(upperBound): # 筛选器都标记为质数 filter=[True for i in range(upperBound+1 ...

  5. UVA10820欧拉函数求互质的对数

    题意: 给出n,算出小于等于n的所有数中,有几对互质: 思路: 利用欧拉函数求与x互质的数的个数prime[x],再将prime[x]递推累加prime[x]=prime[x]+prime[x-1], ...

  6. 埃拉托色尼筛法和欧拉筛法

    筛法 筛法的基本思想是:把从1开始的.某一范围内的正整数从小到大顺序排列, 1不是素数,首先把它筛掉.剩下的数中最小的数是素数,然后去掉它的倍数.依次类推,直到筛子为空时结束. 比如,要产生[2,n] ...

  7. 素数计算之埃氏筛法、欧拉筛法

    埃氏筛法 int main() {const int maxNumber=200;int isPrime[maxNumber];int i;int x;for (i=0;i<maxNumber; ...

  8. UVA10738 Riemann vs Mertens【欧拉筛法】

    One of the biggest, most mathematicians would call it THE biggest, unsolved problems in mathematics ...

  9. UVA12039 Goldbach‘s Cardinality【欧拉筛法】

    Goldbach's cardinality (GC) of an even number means the number of ways the even number can be expres ...

最新文章

  1. python dataframe是什么_python – 逐个构建DataFrame的最快方法是什么?
  2. linux mmap 内存映射【转】
  3. JS Addition
  4. 无法删除文件提示找不到指定文件导致文件无法删除的解决方法
  5. VC.dll相关及其C#交互
  6. 面向对象 —— 结构与设计
  7. python正则匹配ip_python实战系列之正则获取IP地址(八)
  8. 大学校园无线智能调频广播系统
  9. 学术会议论文查重吗_投国际会议论文会查重吗
  10. 字符集编码(一):Unicode 之前
  11. Android Bluetooth HCI log 详解
  12. Linux - chmod授权文件权限命令详解
  13. Could not find artifact org.eclipse.m2e:lifecycle-mapping:pom:1.0.0
  14. 小米手机android目录在哪里设置字体,在哪里修改小米手机的字体大小
  15. 从飞信,超信看中国通讯行业的不作为
  16. Unity 之 ShaderGraph Channel节点解析汇总
  17. 2021年线上线下融合会议需求增长,Hilton EventReady Hybrid Solutions将启动
  18. 服务压测发现怪异现象,一顿排查,揪出“TIME_WAIT”这个内鬼~
  19. QDAS转换器中间XML格式说明文档
  20. mac苹果灯亮出风口烫开不了机解决办法

热门文章

  1. 动态规划——导弹拦截
  2. 做技术的人,工作要踏实。
  3. 服务器系统如何校验md5值,怎么验证md5-NTP的MD5加密
  4. linux超级用户使用,linux窗口下如何使用超级用户?
  5. 学习 java 开发前的准备之JDK配置篇
  6. DBeaver中一些报错的解决
  7. 学习分享|一文搞懂WiFi 6/7 以及选择路由器改造网络那些事
  8. 计算机专业毕业论文java毕业设计网站SSH人事管理系统|人力请假考勤工资人事奖惩[包运行成功]
  9. Genymotion安装及配置简介
  10. 基于Qt的类似QQ好友列表抽屉效果的实现