hdu 4630 查询[L,R]区间内任意两个数的最大公约数
No Pain No Game
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2000 Accepted Submission(s): 851
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.
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.
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
/* hdu 4630 查询[L,R]区间内任意两个数的最大公约数 给你n个数,m个询问,输出区间[l,r]内的任意两个数的最大公约数 对于每一个数而言,对左右都会造成影响,所以我们考虑把查询按r从小到大排序,遇到r则输出结果 像这样的话我们就能只考虑a[i]与 [1,i-1]之间数的关系 因为是求的最大公约数,所以枚举a[i]的因子,如果发现此因子已经出现过,则在此前因子出现的地方赋值 (因为我们是求[l,r]之间的,并不能保证之前因子出现的位置在此之内),然后更新该因子的位置 hhh-2016-04-05 19:55:32 */ #include <iostream> #include <cstdio> #include <cstring> #include <map> #include <algorithm> #include <vector> #include <functional> #define lson (i<<1) #define rson ((i<<1)|1) using namespace std; const int maxn = 5e5+5; int pos[maxn]; int a[maxn]; int tans[maxn]; struct node { int l,r; int Max; int mid() { return (l+r)>>1; } } tree[maxn<<2]; void push_up(int i) { tree[i].Max = max(tree[lson].Max,tree[rson].Max); } void build(int i,int l,int r) { tree[i].l = l,tree[i].r = r; tree[i].Max=0; if(l == r) return ; int mid = tree[i].mid(); build(lson,l,mid); build(rson,mid+1,r); push_up(i); } void update(int i,int k,int val) { if(tree[i].l == tree[i].r && tree[i].l == k) { tree[i].Max = max(tree[i].Max,val); return ; } int mid = tree[i].mid(); if(k <= mid) update(lson,k,val); else update(rson,k,val); push_up(i); } int query(int i,int l,int r) { if(tree[i].l >= l && tree[i].r <= r) { return tree[i].Max; } int ans = 0; int mid = tree[i].mid(); if(l <= mid) ans = max(ans,query(lson,l,r)); if(r > mid) ans = max(ans,query(rson,l,r)); return ans; } struct qy { int l,r; int id; } qry[maxn]; bool cmp(qy a ,qy b) { return a.r < b.r; } int main() { int T; int n; scanf("%d",&T); while(T--) { scanf("%d",&n); build(1,1,n); memset(pos,-1,sizeof(pos)); for(int i = 1; i <= n; i++) scanf("%d",&a[i]); int m; scanf("%d",&m); for(int i = 1; i <= m; i++) { scanf("%d%d",&qry[i].l,&qry[i].r); qry[i].id = i; } sort(qry+1,qry+1+m,cmp); for(int i = 1,cur = 1; i <= n; i++) { for(int j = 1; j*j <= a[i]; j++) { if(a[i]%j == 0) { if(pos[j] != -1) update(1,pos[j],j); if(pos[a[i]/j]!= -1) update(1,pos[a[i]/j],a[i]/j); pos[j] = i; pos[a[i]/j] = i; } } while(i == qry[cur].r && cur <= m) { tans[qry[cur].id] = query(1,qry[cur].l,qry[cur].r); cur ++; } } for(int i = 1; i <= m; i++) { printf("%d\n",tans[i]); } } return 0; }