A positive integer is called a “prime-factor prime” when the number of its prime factors is prime. For example, 12 is a prime-factor prime because the number of prime factors of 12=2×2×3 is 3, which is prime. On the other hand, 210 is not a prime-factor prime because the number of prime factors of 210=2×3×5×7 is 4, which is a composite number.
In this problem, you are given an integer interval [l,r]. Your task is to write a program which counts the number of prime-factor prime numbers in the interval, i.e. the number of prime-factor prime numbers between l and r, inclusive.
输入
The input consists of a single test case formatted as follows.
l r
A line contains two integers l and r (1≤l≤r≤109), which presents an integer interval [l,r]. You can assume that 0≤r−l<1,000,000.
输出
Print the number of prime-factor prime numbers in [l,r].
样例输入
复制样例数据
1 9
样例输出
4
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int M=31623;
const int N=1e6+10;
int num[N],idx,ans=0;
int p[N];
bool vis[N];
int prime[N];
void init()
{
vis[0]=vis[1]=true;
for(int i=2;i<=M;i++)
{
if(!vis[i])
{
prime[idx++]=i;
for(int j=2;i*j<=M;j++)
vis[i*j]=true;
}
}
}
int main()
{
init();
int l,r;
scanf("%d %d",&l,&r);
for(int i=l;i<=r;i++) p[i-l]=i; //题目条件 0≤r−l<1,000,000. 所以我们把区间也映射
if(r<=M) //如果在这个范围内,可以直接暴力过
{
for(int i=0;i<idx;i++)
{
for(int j=l;j<=r;j++)
{
int t=j;
while(t%prime[i]==0) num[j]++,t/=prime[i]; //num[j]保存被分解了多少次
}
}
for(int i=l;i<=r;i++) if(!vis[num[i]]) ans++;
}
else
{
for(int i=0;i<idx;i++)
for(int j=(l+prime[i]-1)/prime[i]*prime[i];j<=r;j+=prime[i]) //这边解释一下j,举个例子2-10区间,2是第一个素数,然后我们要枚举第一个>=l且是2的倍数,后面的数都是2的倍数,然后分解。
{ //为什么要减去一。比如3-10这个区间 且i=1的时候,3是第二个素数,我们要枚举第一个>=3的且是3的倍数。第一个肯定是3 .如股不
//减去1的话,第一个枚举的数将会是6. 如果有不对的地方,请大佬指出
while(p[j-l]%prime[i]==0) num[j-l]++,p[j-l]/=prime[i];
}
for(int i=l;i<=r;i++) if(p[i-l]>1) num[i-l]++; //判断每个数,有没有被全部分解了,如果没有,还要+1;
for(int i=l;i<=r;i++) if(!vis[num[i-l]]) ans++;
}
printf("%d\n",ans);
return 0;
}