Modified GCD
Description
Well, here is another math class task. In mathematics, GCD is the greatest common divisor, and it’s an easy task to calculate the GCD between two positive integers.
A common divisor for two positive numbers is a number which both numbers are divisible by.
But your teacher wants to give you a harder task, in this task you have to find the greatest common divisor d between two integers a and b that is in a given range from low to high (inclusive), i.e. low ≤ d ≤ high. It is possible that there is no common divisor in the given range.
You will be given the two integers a and b, then n queries. Each query is a range from low to high and you have to answer each query.
Input
The first line contains two integers a and b, the two integers as described above (1 ≤ a, b ≤ 109). The second line contains one integer n, the number of queries (1 ≤ n ≤ 104). Then n lines follow, each line contains one query consisting of two integers, low and high (1 ≤ low ≤ high ≤ 109).
Output
Print n lines. The i-th of them should contain the result of the i-th query in the input. If there is no common divisor in the given range for any query, you should print -1 as a result for this query.
Sample Input
Input
9 27
3
1 5
10 11
9 11
Output
3
-1
9
Source
Codeforces Beta Round #67 (Div. 2)
题意:有两个数 a,b 然后有n 个区间,找出每个区间内最大的a,b的公约数,比如a=9,b=27,在区间【3,5】内的最大的公约数就是3了。
分析:首先找出a,b的所有公因数,但怎么求呢,如果直接暴力枚举,肯定不行,会超时,所以,应该先找出a,b的最大公因数,然后找出最大公因数的各个因数就行了。找出最大公因数,用辗转相除法最快,而各个因数只需要枚举到sqrt(最大公因数)就行了。
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<math.h>
#include<queue>
#include<algorithm>
using namespace std;
vector <int> v;
int gcd (int a,int b){//找a b的最大公约数
if (a>b){
while (b!=0){
int temp=a%b;
a=b;
b=temp;
}
return a;
}
else if (a==b)return a;
else {
while (a!=0){
int temp=b%a;
b=a;
a=temp;
}
return b;
}
}
struct node {
int x,y;
};
node t[10005];
void number (int a){//找最大公因数的因数
v.push_back(1);
//不能用a/2为界限,会超时,用sqrt(a),当能整除时,把i和a/i都是因数
for (int i=2;i<=sqrt(a);i++){
if (a%i==0){
v.push_back(i);
v.push_back(a/i);
}
}
}
int main ()
{
int a,b;
int n;
while (scanf ("%d%d",&a,&b)!=EOF){
v.clear() ;
scanf ("%d",&n);
int temp=gcd(a,b);
v.push_back(temp);
number (temp);
sort (v.begin(), v.end()); //排序
for (int i=0;i<n;i++){
int left ,right;
//bool flag=false;
scanf ("%d%d",&t[i].x,&t[i].y);
// 找到比第一个比右端点大的前一个因数与左端点比较
int k=upper_bound (v.begin(),v.end(),t[i].y)-v.begin() -1;
int result = v[k];
if (t[i].x>result)printf ("-1\n");//没在区间内
else printf ("%d\n",result);
}
}
return 0;
}
一开始求各个公因数的时候没有想到枚举到sqrt 就行,直接用了gcd/2,时间就超了。