解题报告: CF75C Modified GCD
题目链接:CF75C Modified GCD
大家都用了一种方法:
\[\text{若}a|x \text{且} b|x,\text{则}\gcd(a,b)|x
\]
然而我只会筛出一个数的因数然后暴力判断是否是另一个数的因数<-这就是我菜的结果了。
后边显然是一个简单二分,但是,
我们发现可能越界(比如找第一个大于他的数,结果......没有?!)
那么我们在最后放一个比较大的数即可。
时间复杂度为 \(\mathcal O(\sqrt{a}+m\log\sqrt{a})=\mathcal O(\sqrt{a}+m\log a)\),可以通过此题。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define read(x) scanf("%d",&x)
int aa,bb;
int x,y;
int m,a[100005],b[100005],cnt=0,c=0;
void get(int n)
{
for(int i=1;i*i<=n;i++)
{
if(!(n%i)) a[++cnt]=i,a[++cnt]=n/i;
if(i*i==n) cnt--;
}
return;
}
void check(int n)
{
for(int i=1;i<=cnt;i++)
{
if(n%a[i]==0) b[++c]=a[i];
}
return;
}
int main()
{
read(aa),read(bb);
if(aa>bb) swap(aa,bb);
get(aa);
check(bb);
sort(b+1,b+c+1);
b[++c]=aa+bb;
read(m);
for(int i=1;i<=m;i++)
{
read(x),read(y);
int l=1,r=c,mid;
while(l<r)
{
mid=(l+r)>>1;
if(b[mid]<x) l=mid+1;
else r=mid;
}
int s=l;
l=1,r=c;
while(l<r)
{
mid=(l+r)>>1;
if(b[mid]<=y) l=mid+1;
else r=mid;
}
int t=l-1;
printf("%d\n",s<=t?b[t]:-1);
}
return 0;
}