poj 2689 区间筛素数

由于区间的右端点非常大(INT_MAX),而区间长度相对小(100W),所以考虑区间筛法,左端点为1的情况需要特判一下。

 1 #include <cstring>

 2 #include <cstdio>

 3 #include <cmath>

 4 using namespace std;

 5 

 6 typedef long long ll;

 7 const int MAX = 9999999;

 8 const int MIN = -1;

 9 const int N = 50000;

10 const int M = 5000;

11 const int K = 1000001;

12 bool visit[N];

13 int prime[M];

14 bool big_visit[K];

15 int big_prime[N];

16 int pn;

17 

18 void sieve( int n )

19 {

20     int r = sqrt( n + 0.5 );

21     memset( visit, 0, sizeof(visit) );

22     visit[0] = visit[1] = 1;

23     for ( int i = 2; i <= r; i++ )

24     {

25         if ( !visit[i] )

26         {

27             for ( int j = i * i; j <= n; j += i )

28             {

29                 visit[j] = 1;

30             }

31         }

32     }

33 }

34 

35 void get_prime( int n )

36 {

37     sieve(n);

38     pn = 0;

39     for ( int i = 0; i <= n; i++ )

40     {

41         if ( !visit[i] )

42         {

43             prime[pn++] = i;

44         }

45     }

46 }

47 

48 int main ()

49 {

50     get_prime( N - 1 );

51     int l, u;

52     while ( scanf("%d%d", &l, &u) != EOF )

53     {

54         memset( big_visit, 0, sizeof(big_visit) );

55         if ( l == 1 ) big_visit[0] = 1;

56         int bound = sqrt( u + 0.5 );

57         for ( int i = 0; prime[i] <= bound; i++ )

58         {

59             int r = ( ( ll ) l + prime[i] - 1 ) / prime[i];

60             if ( r < 2 ) r = 2;

61             for ( ll j = ( ll ) r * prime[i]; j <= ( ll ) u; j += prime[i] )

62             {

63                 big_visit[j - l] = 1;

64             }

65         }

66         int cnt = 0;

67         for ( int i = 0; i <= u - l; i++ )

68         {

69             if ( !big_visit[i] )

70             {

71                 big_prime[cnt++] = i;

72             }

73         }

74         if ( cnt == 1 )

75         {

76             printf("There are no adjacent primes.\n");

77             continue;

78         }

79         int minn = MAX, maxn = MIN, pma = -1, pmi = -1;

80         for ( int i = 0; i < cnt - 1; i++ )

81         {

82             int d = big_prime[i + 1] - big_prime[i];

83             if ( d > maxn )

84             {

85                 maxn = d;

86                 pma = i;

87             }

88             if ( d < minn )

89             {

90                 minn = d;

91                 pmi = i;

92             }

93         }

94         int o1 = big_prime[pmi] + l, o2 = big_prime[pmi + 1] + l;

95         int o3 = big_prime[pma] + l, o4 = big_prime[pma + 1] + l;

96         printf("%d,%d are closest, %d,%d are most distant.\n", o1, o2, o3, o4);

97     }

98     return 0;

99 }

 

你可能感兴趣的:(poj)