约数

时间限制: 1 Sec  内存限制: 128 MB

题目描述

给出两个正整数X和Y,求X和Y的最大公约数,奶牛可以轻松解决这个问题。
农夫Farmer John决定改一改题目去考验奶牛。农夫决定询问奶牛Q个问题,每个问题的格式是这样的:
农夫给定两个正整数a和b,农夫保证a < = b,然后农夫询问奶牛:在a至b的范围内,有没有哪个整数既是X的约数同时又是Y的约数?如果有,输出最大的那个;如果没有,输出-1。

 

输入

第一行,两个正整数,X和Y。
第二行,一个整数数,Q。
接下来有Q行,每行两个正整数:a和b,其中保证a <= b。

 

 

输出

共Q行,每行一个整数,每行对应农夫的一个问题。

 

样例输入

复制样例数据

200  120
3
9  40
25  35
10  15

样例输出

40
-1
10

 

提示

第一个问题:在9至40的范围内,既是200的约数,同时又是120的约数,共有3个,分别是:10,20,40,在3个之中,40最大,所以输出40。
第二个问题:在25至35的范围内,找不到既是200的约数,同时又是120的约数,所以输出-1。
第三个问题:在10至15的范围内,既是200的约数,同时又是120的约数,只有10,所以输出10。

1、对于40%的数据,1<=X<=100,1 <= Y <= 100, 1 <= Q <= 100,1<=a<b<=100
2、对于100%的数据,1<=X<=1000000000,1 <= Y <= 1000000000, 1 <= Q <= 30000,1<=a<b<=1000000000。

求两个数的公约数,先与处理,然后排个序,从最大的开始往下找。

/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>

typedef long long LL;
using namespace std;

int x, y, n, a, b;
vector<int> vec;

int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);

	scanf("%d %d", &x, &y);
	if(x > y) swap(x, y);
	int t = sqrt((double) x);
	for (int i = 1; i <= t; i++){
		if(x % i == 0 && i * i != x){
			if(y % i == 0) vec.push_back(i);
			if(y % (x / i) == 0) vec.push_back(x / i);
		}else if(x % i == 0 && y % i == 0) vec.push_back(i);
	}
	sort(vec.begin(), vec.end());
	int len = vec.size();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++){
		scanf("%d %d", &a, &b);
		int flag = 0;
		for (int j = len - 1; j >= 0; j--){
			if(vec[j] <= b && vec[j] >= a){
				printf("%d\n", vec[j]);
				flag = 1;
				break;
			}else if(vec[j] < a) break;
		}
		if(!flag) printf("-1\n");
	}

	return 0;
}
/**/