link:http://codeforces.com/problemset/problem/1152/C
题目大意:题目要求是求一个k使得(a+k)*(b+k)/ __gcd(a+k,b+k)最小,且在最小的公倍数中找到最小的k.
方法:重点在于:__gcd(a+k,b+k),而__gcd(a+k,b+k)=__gcd(abs(a-b),a+k) (这也可以是__gcd( abs(a-b) ,b+k) ),而gcd( abs(a-b) ,a+k) 一定是abs(a-b) 的因子,找出因子后通过倒推求出k,具体如下:
当(a+k)%因子 != (b+k)%因子 时,即a%因子 != b%因子,表示这个因子不是gcd(a+k,b+k),排除。
当....................==.....................时,表示这个因子就是gcd(a+k,b+k),判断一下题目要求,再求出k(=因子-a%因子)。
红字来由:
//http://codeforces.com/problemset/problem/1152/C
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
ll a,b;
void solve(){
ll i,j;
ll d=abs(a-b);
vector<ll> v;
for(i=1;i*i<=d;++i){
if(d%i==0){
v.push_back(i);
if(i*i!=d){
v.push_back(d/i);
}
}
}
ll ansg=(1ll<<62),ans=0;
sort(v.begin(),v.end());
for(i=0;i<v.size();++i){
int t=v[i];
if(a%t!=b%t) continue;
else if(a%t==0){
ll g=a*b/__gcd(a,b);
if(ansg>g){
ansg=g;
ans=0;
}
}
else{
ll g=(a+t-a%t)*(b+t-b%t)/__gcd((a+t-a%t),(b+t-b%t));
if(g<ansg){
ansg=g;
ans=t-a%t;
}
}
}
cout<<ans<<endl;
}
int main(){
cin>>a>>b;
solve();
return 0;
}