1 /* 2 题意:给一个区间,问任意两个数的素数因子的GCD最大 3 数学+dp:预处理出f[i],发现f[i] <= 7,那么用dp[i][j] 记录前i个f[]个数为j的数有几个, 4 dp[r][j] - dp[l-1][j]表示区间内j的个数,情况不多,分类讨论一下 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cstring> 9 #include <vector> 10 #include <cmath> 11 using namespace std; 12 13 const int MAXN = 1e6 + 10; 14 const int INF = 0x3f3f3f3f; 15 bool is_prime[MAXN]; 16 int f[MAXN]; 17 int dp[MAXN][10]; 18 int cnt[10]; 19 int n; 20 21 int GCD(int a, int b) { 22 return (b == 0) ? a : GCD (b, a % b); 23 } 24 25 void solve(void) { 26 memset (is_prime, true, sizeof (is_prime)); 27 for (int i=2; i<=n; ++i) { 28 if (is_prime[i]) { 29 for (int j=i; j<=n; j+=i) { 30 f[j]++; is_prime[j] = false; 31 } 32 } 33 } 34 } 35 36 void work(void) { 37 memset (dp, 0, sizeof (dp)); 38 for (int i=2; i<=n; ++i) { 39 for (int j=1; j<=7; ++j) { 40 dp[i][j] = dp[i-1][j]; 41 } 42 dp[i][f[i]]++; 43 } 44 } 45 46 int main(void) { //HDOJ 5317 RGCDQ 47 //freopen ("B.in", "r", stdin); 48 n = 1000000; 49 solve (); work(); 50 51 int T; 52 scanf ("%d", &T); 53 while (T--) { 54 int l, r; 55 scanf ("%d%d", &l, &r); 56 bool ok = false; 57 for (int i=7; i>=2; --i) { 58 if (dp[r][i] - dp[l-1][i] >= 2) { 59 printf ("%d\n", i); ok = true; break; 60 } 61 } 62 if (!ok) { 63 if(dp[r][6] - dp[l-1][6] == 1 && dp[r][4] - dp[l-1][4] == 1) { 64 printf("2\n"); 65 } else if(dp[r][6] - dp[l-1][6] == 1 && dp[r][2] - dp[l-1][2] == 1) { 66 printf("2\n"); 67 } else if(dp[r][4] - dp[l-1][4] == 1 && dp[r][2] - dp[l-1][2] == 1) { 68 printf("2\n"); 69 } else { 70 printf("1\n"); 71 } 72 } 73 } 74 75 return 0; 76 }
时间: 2024-10-27 03:18:53