lightoj 1197

问区间内有多少素数,确定了起始位置一直往后挪再标记就行,不知道之前为什么老是TLE,纪念一下吧。

#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <stack>
#include <cstdlib>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>

using namespace std;


const int N = 1e5+5;

int prime[N],all;
int phi[N];
bool is_prime[N];
int vis[N];

void get_phi()
{
    int i, j, k;
    k = 0;
    for(i = 2; i < N; i++)
    {
        if(is_prime[i] == false)
        {
            prime[k++] = i;
            phi[i] = i-1;
        }
        for(j = 0; j<k && i*prime[j]<N; j++)
        {
            is_prime[ i*prime[j] ] = true;
            if(i%prime[j] == 0)
            {
                phi[ i*prime[j] ] = phi[i] * prime[j];
                break;
            }
            else
            {
                phi[ i*prime[j] ] = phi[i] * (prime[j]-1);
            }
        }
    }
    all=k;
}

int main()
{
    get_phi();
    int a,b,T,ncas=0;
    scanf ("%d",&T);
    while (T--)
    {
        int ans=0;
        memset(vis,0,sizeof(vis));
        scanf ("%d%d",&a,&b);
        printf ("Case %d: ",++ncas);
        if (a==1) a=2;
        int fin=sqrt(b),len=b-a+1;
        for (int i=0;prime[i]<=fin&&i<all;i++)
        {
            int st=0;
            if (a%prime[i]!=0) st=prime[i]-a%prime[i];
            if (a<=prime[i]) st+=prime[i];
            while (1)
            {
                if (st<len) vis[st]=1;
                st+=prime[i];
                if (st>=len) break;
            }
//            system("pause");
        }
        for (int i=0;i<len;i++)
        {
            if (vis[i]==0) ans++;
        }
        printf ("%d\n",ans);
    }
    return 0;
}

 

posted on 2016-09-30 16:00  very_czy  阅读(172)  评论(0编辑  收藏  举报

导航