题目描述
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
题意:找出l-r区间内,质因数的个数是素数的数字有多少个。
思路:l,r非常大,最大达到1e9,但是他们的差不超过1e6,其实这个特点已经的区间素数筛非常像了,但是那时候没想到这个和题目有什么关系。。总之,就是,区间内的素数它的质因数只有一个,一定不在答案内,不用管它,我们需要关注的是合数,用埃氏筛法类似的思路,进行优化。
#include<iostream>
#include<cstdio>
#include<cstring>
#pragma GCC optimize(3) //2
using namespace std;
typedef long long ll;
typedef pair<int,int> pa;
const int N = 1e6+10;
const int M =1e6+5;
bool isprime[N];
bool st[N];
int prime[N];
int cnt;
pa f[N];
void init(int n)
{
isprime[1]=isprime[0]=true;
for(int i=2;i<=n;i++)
{
if(!isprime[i])
{
prime[cnt++]=i;
for(int j=i+i;j<=n;j+=i)
isprime[j]=true;
}
}
}
int main()
{
int l,r;
int ans=0;
init(M);
while(~scanf("%d%d",&l,&r))
{
ans=0;
for(int i=l;i<=r;i++)
f[i-l]={i,0};
//cout<<cnt<<endl;
for(int k=0;k<cnt;k++)
{
int i=prime[k];
for(int j=max(2,(l+i-1)/i)*i;j<=r;j+=i)
{
while(f[j-l].first%i==0)
{
f[j-l].first/=i;
f[j-l].second++;
}
}
}
for(int i=l;i<=r;i++)
{
if(f[i-l].first>1)
f[i-l].second++;
if(!isprime[f[i-l].second])
ans++;
}
printf("%d\n",ans);
}
return 0;
}