hdu 5317 筛法+前缀和+暴力

由函数f的定义可以联想到:可以在筛素数(对于普通筛法,每个合数会被自己的素因子筛去一次)的过程中获得函数的值,然后可以发现2,3,5,7,11,13,17,19乘起来已经超过了100W,所以对于100W及以内的数,函数值最多为7.

然后求出前缀和,对于每一个询问,统计出每个区间内函数值为1-7的数字的个数暴力循环获得max gcd。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 1000001;
 7 const int M = 8;
 8 int f[N];
 9 int sum[M][N];
10 int a[M];
11 int pn;
12 
13 void init()
14 {
15     memset( f, 0, sizeof(f) );
16     for ( int i = 2; i < N; i++ )
17     {
18         if ( !f[i] )
19         {
20             f[i] = 1;
21             for ( int j = i + i; j < N; j += i )
22             {
23                 f[j]++;
24             }
25         }
26     }
27     memset( sum, 0, sizeof(sum) );
28     for ( int i = 0; i < N; i++ )
29     {
30         sum[f[i]][i] = 1;        
31     }
32     for ( int i = 1; i < M; i++ )
33     {
34         for ( int j = 1; j < N; j++ )
35         {
36             sum[i][j] += sum[i][j - 1];
37         }
38     }
39 }
40 
41 int gcd( int x, int y )
42 {
43     return y ? gcd( y, x % y ) : x;
44 }
45 
46 int main ()
47 {
48     init();
49     int t;
50     scanf("%d", &t);
51     while ( t-- )
52     {
53         int l, r;
54         scanf("%d%d", &l, &r);
55         int ans = -1;
56         pn = 0;
57         for ( int i = 1; i < M; i++ )
58         {
59             if ( sum[i][r] - sum[i][l - 1] > 1 )
60             {
61                 ans = i;
62             }
63             else if ( sum[i][r] - sum[i][l - 1] == 1 )
64             {
65                 a[pn++] = i;
66             }
67         }
68         for ( int i = 0; i < pn; i++ )
69         {
70             for ( int j = i + 1; j < pn; j++ )
71             {
72                 int tt = gcd( a[i], a[j] );
73                 if ( tt > ans ) ans = tt;
74             }
75         }
76         printf("%d\n", ans);
77     }
78     return 0;
79 }

 

posted @ 2015-07-28 18:21  hxy_has_been_used  阅读(261)  评论(0编辑  收藏  举报