题目链接,很好的一道二分加预处理的题目。
题面:
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.
Examples
Input
9 27 3 1 5 10 11 9 11
Output
3 -1 9
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b)
{
if(b==0) return a;
return gcd(b, a%b);
}
ll x,y,z;
vector<ll> v;
int main()
{
while(scanf("%lld%lld",&x,&y)!=EOF)
{
v.clear();
z=gcd(x, y);
for(int i=1; i*i<=z; i++)
{
/*if(i==1) //可千万别加这一步,加了就会发现upper_bound找有特殊样例(刚好在Test 11会wrong)
{
v.push_back(z);
continue;
}*/
if(z%i==0)
{
v.push_back(z/i);
v.push_back(i);
}
}
sort(v.begin(), v.end());
int T;
scanf("%d",&T);
while(T--)
{
ll e1,e2;
scanf("%lld%lld",&e1,&e2);
/*if(z==1) //剪枝,随便加亦或者不加
{
printf("-1\n");
continue;
}*/
ll p2=upper_bound(v.begin(), v.end(), e2)-v.begin()-1;
ll res=v[p2];
if(res<e1) printf("-1\n");
else printf("%lld\n",res);
}
}
return 0;
}