No Pain no GameTime limit:4000/2000 MS (java/others) Memory limit:65536/32768 K (java/others)
Total submission (s): 1820 Accepted Submission (s): 778 Links: Hdu 4630 Problem Descriptionlife is a Game,and your lose it,so you suicide. But you can not kill yourself before your solve this problem: Given you a sequence of number A1, A2, ..., an. They is also a permutation of 1...N. You need to answer some queries,each with the following format: If we chose the number a A, a (shouldn ' t be the same) from interval [L, R],what is the maximum gcd (A, b)? If there's no-to choose-distinct number (L=R) then the-answer is zero. Inputfirst line contains a number T (T <= 5), denote the number of test cases. Then follow T test cases. For each test cases,the first line contains a number n (1 <= n <= 50000). The second line contains n number a1, A2, ..., an. The third line contains a number Q (1 <= Q <= 50000) denoting the number of queries. Then Q lines Follows,each lines contains the integer l, r (1 <= l <= r <= N), denote a query. Outputfor each test cases,for each query print the answer on one line. Sample Input1108 2 4 9 5 7 10 6 1 352 102 46 91 47 10 Sample Output52243 Test InstructionsGiven n number, this n number is an arrangement of 1~n, and then given Q query, each time an interval [l,r], in the [l,r] this interval to find the largest gcd (a, B), {l<=a<=b<=r}. AnalysisHere I link a Daniel's puzzle, I think he is very good at solving the puzzle. I just add that HDU has a set of data is definitely wrong, 1 1 1 1 1 The correct answer is 1. However, Hangzhou Electric's data is indeed 0 ... I wa for a few hours but I can't solve it. Tragedy, Woo-hoo ~~~~~ /****************************>>>>headfiles<<<<****************************/#include <set> #include <map> #include <list> #include <cmath> #include <queue> #include <vector > #include <cstdio> #include <string> #include <cstring> #include <iomanip> #include < iostream> #include <sstream> #include <algorithm>using namespace std;/**************************** >>>>>define<<<<<*****************************/#define FST First#define snd Second#define Root 1,n,1#define LRT rt<<1#define RRT rt<<1|1#define Lson l,mid,rt<<1#define Rson mid+1,r,rt<<1|1#define PB (a) push_back (a) #define MP (A, B) Make_pair (A, b) #define CASE (T) for (scanf ("%d", &t); t--;) #define FIN freopen ("Input.txt", "R", stdin) #define FOUT freopen ("Output.txt", "w", StdoUT)//#pragma comment (linker, "/stack:1024000000,1024000000") const int INF = 0x3f3f3f3f;const int maxn = 50000 + 5;/******* >>>>separator<<<<****************************/struct Node{int L, R, Id Node () {} node (int _l, int _r, int _id): L (_l), R (_r), id (_id) {} BOOL operator < (const node& p) Const { return R < P.R; }};vector<node> asks;int T, N, Q;int A[MAXN], PRE[MAXN], ANS[MAXN], SEGTREE[MAXN << 2];vector<int> Fact Or[maxn];void Init () {for (int i = 1, i < MAXN; i++) for (int j = i; J < maxn; J + = i) factor[j]. PB (i);} inline void pushup (const int& RT) {Segtree[rt] = max (SEGTREE[LRT], SEGTREE[RRT]);} void Update (const int& POS, const int& val, int l, int r, int rt) {if (L = = r) {Segtree[rt] = max (seg TREE[RT], Val); Return } int mid = (L + r) >> 1; if (POS <= mid) Update (POS, Val, Lson); Else Update (POS, Val, RSON); Pushup (RT);} int Query (const int& L, const int& R, int L, int R, int rt) {if (L <= l && R <= R) {RET Urn segtree[rt];//return max (1, segtree[rt]); is the two-digit greatest common divisor not necessarily greater than 1??? Same as} int mid = (L + r) >> 1, ret = 0; 1; Ibid. if (l <= mid) ret = max (ret, Query (L, R, Lson)); if (R > Mid) ret = max (ret, Query (L, R, Rson)); return ret;} int main () {//FIN; Init (); Case (T) {scanf ("%d", &n); for (int i = 1; I <= N; i++) scanf ("%d", &a[i]); scanf ("%d", &q); Asks.clear (); for (int i = 1, l, R; I <= Q; i++) {scanf ("%d%d", &l, &r); ASKS.PB (Node (L, R, I)); } sort (Asks.begin (), Asks.end ()); memset (Pre,-1, sizeof (pre)); memset (segtree, 0, sizeof (segtree)); int cnt = 0; for (int i = 1, i <= N; i++) {for (int j = 0; J < Factor[a[i]].size (); j + +) { int &f = Factor[a[i]][j]; if (pre[f]! =-1) {Update (pre[f], F, root); } Pre[f] = i; } while (CNT < Q && ASKS[CNT].R = = i) {int &l = ASKS[CNT].L, &r = ASKS[CNT].R, &id = asks[cnt].id; Ans[id] = Query (L, R, Root); cnt++; } if (CNT >= Q) break; } for (int i = 1; I <= Q; i++) printf ("%d\n", Ans[i]); } return 0;}
|