原题链接:最多约数问题
解题思路:
首先,考虑如何求解一个数有多少个约数,1的约数只有1个,其他的数字,对其进行质因数分解
可以得到 a = b1^c1 * b2^c2 * b3^c3 * ....如下结果,根据排列组合原理可以得到其约数个数为(c1+1)*(c2+1)*(c3+1)*....
而对于一个数质因数分解的效率,最暴力的方法为sqrt(n),就算进行优化,也只能接近logn
对于本题的数据范围而言,nlogn(n=500w)时间来说效率还是太低。
所以我们需要O(n)的算法。
考虑的质因数分解实质上是质数的提取过程,我们可以利用线性素数筛法来O(n)的计算n里面的素数个数
同时,线性筛的原理或者说过程的操作,其实恰好符合了约数个数的求解过程。
对于
a = b1^c1 * b2^c2 * b3^c3
d = b1^(c1+1) * b2^c2 * b3^c3
上述两个数的约数关系就是 div(d) = div(a) / (c1+1) * (c1+2)
所以可以直接在线性筛的过程中求解出每个数的约数个数,然后就是循环求最大值了。
注意事项: 特判 1 1 这组测试数据
参考代码:
#include<cstdio> #include<algorithm> using namespace std; const int N = 5e6 + 10; int f[N], p[N], d[N]; int l, r; int main() { scanf("%d%d", &l, &r); int ans = 1, t = 0; for (int i = 2; i <= r; i++) { if (!f[i]) p[t++] = i, f[i] = d[i] = 2; for (int j = 0; j < t && i * p[j] <= r; j++) { f[i * p[j]] = 2; d[i * p[j]] = d[i] * 2; if (i % p[j] == 0) { f[i * p[j]] = f[i] + 1; d[i * p[j]] = d[i] / f[i] * f[i*p[j]]; break; } } if (i >= l) ans = max(ans, d[i]); } printf("%d\n", ans); return 0; }
0.0分
3 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复