数学+dp HDOJ 5317 RGCDQ
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 }
编译人生,运行世界!