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 链接:hdu 4630 Problem Description Life is a game,and you lose it,so you suicide. But you can not kill yourself before you solve this problem: Given you a sequence of number a1, a2, ..., an.They are also a permutation of 1...n. You need to answer some queries,each with the following format: If we chose two number a,b (shouldn‘t be the same) from interval [l, r],what is the maximum gcd(a, b)? If there‘s no way to choose two distinct number(l=r) then the answer is zero. Input First 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 two integer l, r(1 <= l <= r <= n),denote a query. Output For each test cases,for each query print the answer in one line. Sample Input 1 10 8 2 4 9 5 7 10 6 1 3 5 2 10 2 4 6 9 1 4 7 10 Sample Output 5 2 2 4 3 题意给定N个数,这N个数是1~N的一种排列,然后给定Q个询问,每次询问一个区间[l,r],在[l,r]这个区间中求最大的gcd(a,b) , {l<=a<=b<=r}。 分析这里我链接一个大牛的题解,我觉得他的题解讲得挺好的。我这里只补充一句,hdu有组数据是肯定错了, 1 1 1 1 1 正确答案是1才对。然而,杭电的数据确实0。。。 害得我WA了几个小时却不得其解。悲剧,呜呜呜~~~~~ /****************************>>>>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> factor[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(segtree[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) { return segtree[rt]; // return max(1, segtree[rt]); 难道两个数的最大公约数不是一定大于1的么???下同 } int mid = (l + r) >> 1, ret = 0; //1; 同上 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; } |
版权声明:本文为博主原创文章,未经博主允许不得转载。