问题:
定义N(x)是x的质因数个数,f(x) = [1/N(x)],[x]表示向下取整。
输入x ,请输出答案 ∑ni=1f(x) 。
1<=x<=10^6.
分析:
一般枚举肯定是要超时的,
打表解决。上答案!(有点难想)
f(x)=[1/N(x)]的取值,只能是 0 或 1 ! 因为向下取整。当质因数个数大于1 时,倒数就小于1了!!一向下取整就是0!!!!
思考:
每个数(1除外)都至少有一个质因数!
如上文所说,质因数个数大于1的数,,就 把它的个数看作0!!
所以只需要考虑哪些数的质因数只有一个!!(解题的关键,个人觉得也是难点!!!)
1、质数的质因数一定是1个。
2、质数的平方的质因数一定是1个。
3(总结)、不止是平方,,质数的n次方的质因数一定只有他本身!!!!
仔细想想,质因数只有一个的数没有其他的情况了。
因为每个数(1除外)都至少有一个质因数!而只有质数的质因数是它本身!!
所以 ,假设不是这种情况,那么他的其中一个约数因数一定可以再分解成另一个质数!!!!
下面的是打表了。。
#include <stdio.h>
const int MAXN = (int)1e6 + 5;
int p[MAXN], cnt[MAXN]; // 定义全局变量时,数组自动初始化为0!!!!!学习了!!!
void init() //打表。
{
for(int i = 2; i * i < MAXN; ++i) //先是素数打表
{
if(!p[i]) //当p[i]是0的时候 (初始p[i]都是0)
{
for(int j = i * i; j < MAXN; j += i)
{
p[j] = 1; // 所有的合数项标记为1 !!!!
}
}
}
for(int i = 2; i < MAXN; ++i)
{
if(!p[i]) //当p[i] 是 0 的时候,此时是当i是素数时(从2开始)
{
for(long long j = i; j < MAXN; j *= i) j 是素数的 n次方!!!!!
{
cnt[j] = 1; // cnt[] 的素数的 n次方 数项都是1。。!!!
}
}
}
for(int i = 1; i < MAXN; ++i)
{
cnt[i] += cnt[i - 1]; //这样 cnt[i] 就是1--n的质因数个的倒数的累加了!!
}
}
int main()
{
init();
int n;
while(scanf("%d", &n) != EOF)
{
printf("%d\n", cnt[n]);
}
return 0;
}