Help Hanzo lightof 1197 求一段区间内素数个数,[l,r] 在 [1,1e9] 范围内。r-l<=1e5; 采用和平常筛素数的方法。平移区间即可。

/**
题目:Help Hanzo lightof 1197
链接:https://vjudge.net/contest/154246#problem/M
题意:求一段区间内素数个数,[l,r] 在 [1,1e9] 范围内。r-l<=1e5;
思路:采用和平常筛素数的方法。平移区间即可。

*/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+10;
const double eps = 1e-6;
ll prime[maxn/10];
int flag[maxn], pr;
void init()
{
    ll mas = (1LL<<31)-1;
    ll N = sqrt(mas+0.5);
    //cout<<"N = "<<N<<endl;
    //cout<<"mas = "<<mas<<endl;
    for(ll i = 2; i<=N; i++){
        if(flag[i]==0){
            for(ll j = i*i; j<=N; j+=i){
                flag[j] = 1;
            }
        }
    }
    pr = 0;
    for(int i = 2; i <= N; i++){
        if(flag[i]==0){
            prime[pr++] = i;
        }
    }
    //cout<<"pr = "<<pr<<endl;
}
int main()
{
    int T;
    int cas = 1;
    cin>>T;
    init();
    while(T--)
    {
        int l, r;
        scanf("%d%d",&l,&r);
        memset(flag, 0, sizeof flag);
        int sr = sqrt(r+0.5);
        for(int i = 0; i<pr&&prime[i]<=sr; i++){
            ///当l=2147483647 即:2^31 -1 的时候,j=0; 那么j-l<0; Runtime error所以这里要处理一下。改为long long型。
            for(ll j = max((l-1)/prime[i]*prime[i]+prime[i],prime[i]*prime[i]); j <= r; j+=prime[i]){
                flag[j-l] = 1;
            }
        }
        int cnt = 0;
        for(ll i = max(l,2); i <= r; i++){///当i = r , i++之后,i=0;那么又会重新开始,无线循环。然后导致i-l溢出。改为long long。
            if(flag[i-l]==0){
                cnt++;
            }
        }
        printf("Case %d: %d
",cas++,cnt);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xiaochaoqun/p/6722563.html