区间素数筛
Posted lengsong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间素数筛相关的知识,希望对你有一定的参考价值。
题目描述
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.
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.
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<bits/stdc++.h> #pragma GCC optimize(3) using namespace std; typedef long long ll; const int maxn=1e6+5; int prime[maxn],v[40005],cnt,num[maxn],str[maxn];//num是保存因子个数,str是lr区间里面的数 int vis[38]= 0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1;//判断因子个数是否素数 void getp(int n)//得到sqrt(r)内的素数,线性筛 for(register int i=2; i<=n; ++i) if(v[i]==0) v[i]=i,prime[++cnt]=i; for(register int j=1; j<=cnt; ++j) if(prime[j]>v[i]||prime[j]>n/i) break; v[i*prime[j]]=prime[j]; int main() int l,r,templ,tempr,poi; scanf("%d %d",&l,&r); int len=r-l+1; getp(sqrt(r)); for(register int i=l; i<=r; ++i)//赋值 str[i-l+1]=i; for(register int j=1; j<=cnt; ++j)//对sqrt(r)内的素数进行枚举 templ=ceil(l/(prime[j]*1.0));//i的左区间边际 tempr=floor(r/(1.0*prime[j]));//i的右区间边际 for(register int i=templ; i<=tempr; ++i)//枚举i poi=i*prime[j]-l+1; if(poi>len)continue; while(str[poi]%prime[j]==0)//除去因子 str[poi]=str[poi]/prime[j],++num[poi]; int ans=0; for(register int i=1; i<=len; ++i)//当str[i]还不为1时说明质因子个数还得加1,因为不为1的数肯定剩下的是素数 if((str[i]==1&&vis[num[i]])||(str[i]!=1&&vis[num[i]+1]))++ans; printf("%d\n",ans); return 0;
以上是关于区间素数筛的主要内容,如果未能解决你的问题,请参考以下文章