洛谷传送门

题目描述

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 dd between two integers aa and bb that is in a given range from lowlow to highhig**h (inclusive), i.e. low<=d<=highlow<=d<=hig**h . It is possible that there is no common divisor in the given range.

You will be given the two integers aa and bb , then nn queries. Each query is a range from lowlow to highhig**h and you have to answer each query.

输入格式

The first line contains two integers aa and bb , the two integers as described above ( 1<=a,b<=10^{9}1<=a,b<=109 ). The second line contains one integer nn , the number of queries ( 1<=n<=10^{4}1<=n<=104 ). Then nn lines follow, each line contains one query consisting of two integers, lowlow and highhig**h ( 1<=low<=high<=10^{9}1<=low<=hig**h<=109 ).

输出格式

Print nn lines. The ii -th of them should contain the result of the ii -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.

题意翻译

题目大意:

找出a,b的最大公因子,然后给几个查询,每次查询包含x,y两个数字,查询在x~y之间的a,b的最大公因子

Translated by @Harryheqg


题解:

关键性质:

两个数的任意公因子一定是其最大公因子的因子。

这个性质的正确性是显然的。

如果数感不太好,完全可以用反证法证明一下。

然后就自然而然地想到先求gcd,再处理gcd的所有约数,再在其上二分查找。

二分查找的形式多种多样,可以手动,也可以STL upper_bound,你要是喜欢,打一棵权值线段树也没人管你。

我用的是upper_bound:

代码:

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int a,b;
vector<int> v;
int gcd(int a,int b)
{
	return !b?a:gcd(b,a%b);
}
void fac(int x)
{
	for(int i=1;i<=sqrt(x);i++)
		if(x%i==0)
		{
			v.push_back(i),v.push_back(x/i);
			if(i==x/i)
				v.pop_back();
		}
}
int main()
{
	scanf("%d%d",&a,&b);
	int g=gcd(a,b);
	fac(g);
	sort(v.begin(),v.end());
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		int pos=upper_bound(v.begin(),v.end(),y)-v.begin();
		pos--;
		if(v[pos]<x)
			puts("-1");
		else
			printf("%d\n",v[pos]);
	}
	return 0;
}

相关文章:

  • 2021-05-25
  • 2022-01-27
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-10
猜你喜欢
  • 2022-12-23
  • 2021-12-07
  • 2022-02-11
  • 2021-06-12
  • 2021-12-15
  • 2021-10-04
相关资源
相似解决方案