文章标题 codeforces 75C:Modified GCD (二分+最大公因数)

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,时间就超了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值