Prime-Factor Prime

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值