由函数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 }
时间: 2024-10-24 11:32:33