Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and more interesting things about GCD. Today He comes up with Range Greatest Common Divisor Query (RGCDQ). What’s RGCDQ? Please let me explain it to you gradually. For a positive integer x, F(x) indicates the number of kind of prime factor of x. For example F(2)=1. F(10)=2, because 10=2*5. F(12)=2, because 12=2*2*3, there are two kinds of prime factor. For each query, we will get an interval [L, R], Hdu wants to know maxGCD(F(i),F(j)) (L≤i<j≤R)
There are multiple queries. In the first line of the input file there is an integer T indicates the number of queries.
In the next T lines, each line contains L, R which is mentioned above.
All input items are integers.
1<= T <= 1000000
2<=L < R<=1000000
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <string>
5 #include <cmath>
6 #include <algorithm>
7 #include <vector>
8 #include <queue>
9 #include <set>
10 #include <map>
11 #include <stack>
12 #include <limits.h>
13 using namespace std;
14 typedef long long LL;
15 #define lson l, mid, rt << 1
16 #define rson mid + 1, r, rt << 1 | 1
17 #define y1 y234
18 #define MAXN 1000010 // 1e6
19 int t;
20 bool vis[MAXN];
21 int F[MAXN], ans[MAXN], last[MAXN];
22 int tree[MAXN * 2 + 100000];
23 struct node {
24 int id, L, R;
25 node(int L, int R, int id) :L(L), R(R), id(id) {}
26 bool operator < (const node &w) const {
27 return R < w.R;
28 }
29 };
30 vector<node> Q;
31 vector<int> Fyinshu[MAXN];
32 void init() {
33 vis[0] = vis[1] = true;
34 for(int i = 2; i <= 1000000; i++) {
35 if(!vis[i]) {
36 F[i]++;
37 for(int j = i + i; j <= 1000000; j += i) {
38 vis[j] = 1;
39 F[j]++;
40 }
41 }
42 }
43 }
44 void Pushup(int rt) {
45 tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]);
46 }
47 void Update(int num, int pos, int l, int r, int rt) {
48 if(l == r) {
49 tree[rt] = max(tree[rt], num);
50 return;
51 }
52 int mid = (l + r) >> 1;
53 if(pos <= mid) Update(num, pos, lson);
54 else Update(num, pos, rson);
55 Pushup(rt);
56 }
57 int Query(int st, int ed, int l, int r, int rt) {
58 int res = 0;
59 int mid = (l + r) >> 1;
60 if(st <= l && r <= ed) {
61 return tree[rt];
62 }
63 if(st <= mid) res = max(res, Query(st, ed, lson));
64 if(ed > mid) res = max(res, Query(st, ed, rson));
65 return res;
66 }
67 int main() {
68 init();
69 scanf("%d", &t);
70 int st, ed, maxn = -1;
71 for(int i = 1; i <= t; i++) {
72 scanf("%d%d", &st, &ed);
73 Q.push_back(node(st, ed, i));
74 maxn = max(maxn, ed);
75 }
76 sort(Q.begin(), Q.end());
77 for(int i = 1; i <= maxn; i++) {
78 int tmp = F[i];
79 Fyinshu[tmp].clear();
80 for(int j = 1; j * j <= tmp; j++) {
81 if(tmp % j != 0) continue;
82 Fyinshu[tmp].push_back(j);
83 if(j * j != tmp) Fyinshu[tmp].push_back(tmp / j);
84 }
85 }
86 int q_cnt = 0;
87 for(int i = 1; i <= maxn && q_cnt < t; i++) {
88 int len = Fyinshu[F[i]].size();
89 for(int j = 0; j < len; j++) {
90 int tmp = Fyinshu[F[i]][j];
91 if(last[tmp] != 0) {
92 Update(tmp, last[tmp], 1, maxn, 1);
93 }
94 last[tmp] = i;
95 }
96 for(; i == Q[q_cnt].R; q_cnt++) {
97 if(Q[q_cnt].L == Q[q_cnt].R) ans[Q[q_cnt].id] = 0;
98 ans[Q[q_cnt].id] = Query(Q[q_cnt].L, Q[q_cnt].R, 1, maxn, 1);
99 }
100 }
101 for(int i = 1; i <= t; i++)
102 printf("%d\n", ans[i]);
103 return 0;
104 }