/** 题目: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; }