题意:http://www.lightoj.com/volume_showproblem.php?problem=1197
在区间内一共有多少个数学 包括首尾数字
因为数字比较大 并且两者差值比较小 那么我们就将状态转移
【e,f】到【0,f-e】从e 开始判断每个素数的倍数 然后在【0,f-e】中标记
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<math.h> #include<string> #include<vector> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define N 100006 int q[N],ans=0,a[N],w[N]; void prime() { for(int i=2;i<N;i++) { if(!a[i]) { q[ans++]=i; for(int j=i;j<N;j+=i) a[j]=1; } } } int main() { int T,t=1; prime(); scanf("%d",&T); while(T--) { int e,f,sum=0; memset(w,0,sizeof(w)); scanf("%d%d",&e,&f); int l=f-e;///状态转移 for(int i=0; i<ans&&q[i]*q[i]<=f; i++) { int j=0; if(e%q[i]!=0)///判断e+j如果(e + j)% q[i] != 0,则将e + j筛除 j=j+q[i]-e%q[i]; if(j+e==q[i])///如果e+ j是素数,则找下一个 j+=q[i]; for(; j<=l; j+=q[i]) ///从j开始将含q[i]因子的数标记(即筛除) w[j]=1; } for(int i=0; i<=l; i++) if(!w[i]) sum++; if(e==1)///e从1开始要减去 sum--; printf("Case %d: %d ",t++,sum); } return 0; }