素数密度_NOI导刊2011提高(04)
题目描述
给定区间[L, R](L <= R <= 2147483647,R-L <= 1000000),请计算区间中素数的个数。
输入
两个数 L 和 R。
输出
一行,区间中素数的个数。
样例输入
2 11
样例输出
5
可以发现R - L范围很小,但L和R很大,用普通的筛法时空间都会超。
但可以转换思路,只筛L ~ R的素数。
此前先筛出2-√r的素数,只有大约47000个
将这些素数在L ~ R里的倍数筛掉,注意别把素数本身筛掉
比如样例:2~11,会把2,3筛掉。如果没有注意的话小数据会过不了(大的可以过,亲测只有样例不行)
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; long long l,r; int k; int prime[4000001]; int vis[4000001]; int ans; int main() {long long i,j,p; cin>>l>>r; for (i=2;i<=sqrt(sqrt(r));i++) if (vis[i]==0) { for (j=i*i;j<=sqrt(r);j+=i) vis[j]=1; } for (i=2;i<=sqrt(r);i++) if (vis[i]==0) { k++; prime[k]=i; } memset(vis,0,sizeof(vis)); for (i=1;i<=k;i++) { int x=(int)(l/prime[i]+0.5); for (j=x*prime[i];j<=r;j+=prime[i]) if (j%prime[i]==0&&j/prime[i]>1) vis[j-l]=1; } for (i=l;i<=r;i++) if (vis[i-l]==0) {//cout<<i<<endl; ans++; } cout<<ans; }