Contest1656 - 2019年我能变强组队训练赛第六场 问题 C: 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

题意:找出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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值