CtrlCV工程师


私信TA

用户名:Occult

访问量:3046

签 名:

过去的过不去的都过去了

等  级
排  名 20266
经  验 704
参赛次数 3
文章发表 2
年  龄 22
在职情况 在职
学  校 zufe
专  业

  自我简介:

常年划水

TA的其他文章

解题思路:

首先,考虑如何求解一个数有多少个约数,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分

5 人评分

新上线《蓝桥杯辅导》课程,近五年的蓝桥杯省赛与国赛真题都有,从读题开始理解题意、梳理思路、实现代码再提交评测全过程,可有效提升获奖比例甚至进国赛!课程介绍、试听请猛击这里

  评论区

能推出这个迭代公式真不容易.
2018-08-07 18:30:15
  • «
  • 1
  • »