codeforces1152C. Neko does Maths

题目链接 琪亚娜世界第一可爱

给出a和b,求
max ⁡ k ≥ 0 l c m ( a + k , b + k ) \max _{k \geq 0} lcm(a+k,b+k) k0maxlcm(a+k,b+k)


首先,gcd与lcm有如下关系
l c m ( a + k , b + k ) = ( a + k ) ⋅ ( b + k ) g c d ( a + k , b + k ) lcm(a+k,b+k)=\frac{(a+k) \cdot (b+k)}{gcd(a+k,b+k)} lcm(a+k,b+k)=gcd(a+k,b+k)(a+k)(b+k)
g c d ( a + k , b + k ) = g c d ( a − b , a + k ) gcd(a+k,b+k)=gcd(a-b,a+k) gcd(a+k,b+k)=gcd(ab,a+k)
所以根据上述关系,可知a+k与b+k的公因数一定是a-b的因数,先假设这个公因数为a-b的因数q,那么a+k与b+k也需要满足 a + k ≡ b + k ( m o d q ) a+k \equiv b+k \pmod q a+kb+k(modq) a + k m o d    q = 0 a+k \mod q=0 a+kmodq=0
也就是
a ≡ b ( m o d q ) a \equiv b \pmod q ab(modq)
a − b ≡ 0 ( m o d q ) a-b \equiv 0 \pmod q ab0(modq)
这样就证明了存在一个k,能使得q为a+k和b+k的最大公因数。
当a mod q !=0 时k为
k = q − a m o d    q k=q-a\mod q k=qamodq
否则k为0


#include <stdio.h>
#include <climits>
#include <cstring>
#include <time.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <vector>
#include <string>

#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return

#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;

ll gcd(ll a,ll b)
{
	if(a<b)
		return gcd(b,a);
	if(b==0)
		return a;
	if(a%2)
	{
		if(b%2)
			return gcd(b,a-b);
		else
			return gcd(a,b>>1);
	}
	else
	{
		if(b%2)
			return gcd(a>>1,b);
		else
			return 2*gcd(a>>1,b>>1);
	}
}
ll lcm(ll a,ll b){
    re a*b/gcd(a,b);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    ll a,b;
    cin>>a>>b;
    if(a<b)     //maxn=a
        swap(a,b);
    int k=0;
    ll dif=a-b;
    ll num=lcm(a,b);
    for(ll i=1;i*i<=dif;i++){
        if(dif%i)
            continue;
        ll add=i-a%i;
        ll n1=(a+add)/i,n2=(b+add)/i;
        ll temp=lcm(n1,n2)*i;
        if(temp<num){
            num=temp;
            k=add;
        }

        ll n=dif/i;
        add=n-(a%n);
        n1=(a+add)/n,n2=(b+add)/n;
        temp=lcm(n1,n2)*n;
        if(temp<num){
            num=temp;
            k=add;
        }
    }

    cout<<k<<endl;

    re 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值