题意: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\n",t++,sum);
    }
    return 0;
}

 

posted on 2017-10-24 11:00  云胡不喜。  阅读(144)  评论(0编辑  收藏  举报