HDU 4630 No Pain No Game 线段树 和 hdu3333有共同点
No Pain No Game
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1465 Accepted Submission(s):
631
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
Source
1 /** 2 题意:求解区间[ L , R ] max gcd() ; 3 4 如果只求一次,那么我们可以这样做。 5 把每个数字的因子刷一遍,满足>=2的最大就是结果。 6 如果多次,可以这样求解。 7 在区间[ L , R ] 如果素因子出现,更新它上次出现的位置的最大值, 8 保存当前出现的位置。第一次出现不更新,只保存。 9 10 当枚举到R的时候,我们就可以在[ L, R ]中找最大值即可。 11 12 所以这一题就可以对r 排序,然后进行更新。 13 **/ 14 #include<iostream> 15 #include<stdio.h> 16 #include<cstring> 17 #include<cstdlib> 18 #include<algorithm> 19 #include<vector> 20 using namespace std; 21 22 vector<int>yz[50002]; 23 struct node 24 { 25 int l,r,len; 26 int maxn; 27 }f[50002*4]; 28 struct node2 29 { 30 int st,ed; 31 int i,val; 32 }a[50002]; 33 int date[50002]; 34 int pre[50002]; 35 36 bool cmp(struct node2 n1,struct node2 n2) 37 { 38 return n1.ed<n2.ed; 39 } 40 bool cmp1(struct node2 n1,struct node2 n2) 41 { 42 return n1.i<n2.i; 43 } 44 void init() 45 { 46 for(int i=1;i<=50000;i++) 47 for(int j=i;j<=50000;j=j+i) 48 yz[j].push_back(i); 49 } 50 void build(int l,int r,int n) 51 { 52 int mid = (l+r)/2; 53 f[n].l = l; 54 f[n].r = r; 55 f[n].len = f[n].r-f[n].l +1; 56 f[n].maxn = 0; 57 if(l==r) return; 58 build(l,mid,n*2); 59 build(mid+1,r,n*2+1); 60 } 61 void update(int wz,int num,int n) 62 { 63 int mid=(f[n].l + f[n].r)/2; 64 if(f[n].l == wz && f[n].r == wz) 65 { 66 if(f[n].maxn<num) 67 f[n].maxn = num; 68 return; 69 } 70 if(mid>=wz) update(wz,num,n*2); 71 else if(mid<wz) update(wz,num,n*2+1); 72 f[n].maxn = f[n*2].maxn>f[n*2+1].maxn ? f[n*2].maxn : f[n*2+1].maxn; 73 } 74 int query(int l,int r,int n) 75 { 76 int mid=(f[n].l + f[n].r)/2; 77 if(f[n].l == l && f[n].r == r) 78 { 79 return f[n].maxn; 80 } 81 if(mid>=r) return query(l,r,n*2); 82 else if(mid<l) return query(l,r,n*2+1); 83 else return max(query(l,mid,n*2),query(mid+1,r,n*2+1)); 84 } 85 int main() 86 { 87 int T , n , m; 88 init(); 89 scanf("%d",&T); 90 while(T--) 91 { 92 scanf("%d",&n); 93 build(1,n,1); 94 for(int i=1;i<=n;i++) 95 scanf("%d",&date[i]); 96 scanf("%d",&m); 97 for(int i=1;i<=m;i++) 98 { 99 scanf("%d%d",&a[i].st,&a[i].ed); 100 a[i].i = i; 101 a[i].val = 0; 102 } 103 sort(a+1,a+1+m,cmp); 104 memset(pre,0,sizeof(pre)); 105 int k = 1; 106 for(int i=1;i<=n;i++) 107 { 108 int ans = yz[date[i]].size(); 109 for(int j=0;j<ans;j++) 110 { 111 int temp = yz[date[i]][j]; 112 if(pre[temp]) 113 update(pre[temp],temp,1); 114 pre[temp] = i; 115 } 116 while(a[k].ed == i && k<=m) 117 { 118 a[k].val = query(a[k].st,a[k].ed,1); 119 k++; 120 } 121 } 122 sort(a+1,a+1+m,cmp1); 123 for(int i=1;i<=m;i++) printf("%d\n",a[i].val); 124 } 125 return 0; 126 }