传送门

题意

  给出两个正整数 a,b;

  求解 k ,使得 LCM(a+k,b+k) 最小,如果有多个 k 使得 LCM() 最小,输出最小的k;

思路

  刚开始推了好半天公式,一顿xjb乱操作;

  后来,看了一下题解,看到一个引理:

  GCD(a,b) = GCD(a,b-a) = GCD(b,b-a);

假设GCD(a,b) = c;
a%c = ;
b%c = ;
那么(b-a)%c = ;
这证明了a和(b-a),b和(b-a)有公约数c;
假设GCD(a,b-a)=c' > c;
那么,a%c' = 0;
(b-a)%c' = 0;
(b-a)%c' = b%c'-a%c';
所以 b%c' = 0;
那么GCD(a,b) = c' > c,与假设矛盾;
GCD(b,b-a)同理;
故命题得证;

简单证明

  有了这个引理后,解题思路变得异常清晰;

  首先,令 b > a;

  将 LCM(a+k,b+k) 转化一下:

  

  

  情况①,如果 a 与 b-a 不互素,那么 a+1 与 b-a 一定互素;

  情况②,a+k = x·(b-a),其中 x·(b-a) 是大于等于 a 的最小的 (b-a) 的倍数;

  情况③,枚举 b-a 的约数;

•Code

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long ll a,b; ll GCD(ll a,ll b)
{
return a == ? b:GCD(b%a,a);
}
ll LCM(ll a,ll b)
{
return a/GCD(a,b)*b;
}
ll F(ll k)
{
return (a+k)*(b+k)/GCD(a+k,b+k);
}
bool isSat(int i,ll k)//判断k是否可以更新为i-a
{
ll curK=i-a;
if(curK < || F(curK) != LCM(a+curK,b+curK))
return false;
if(F(curK) < F(k) || F(curK) == F(k) && curK < k)
return true;
return false;
}
ll Solve()
{
if(a > b)
swap(a,b);
int d=b-a;
if(d == )
return ; ll k=;
for(;GCD(d,a+k) != ;k++);///情况①
for(int i=;i*i <= d;++i)///情况③
{
if(d%i != )
continue;
if(isSat(i,k))///a+k=i
k=i-a;
if(isSat(d/i,k))///a+k=d/i
k=d/i-a;
}
///情况②,GCD()为定值,k越小LCM()就越小
ll x=(a/d+(a%d == ? :))*d;///a+k=k*d(k*d:>=a的最小的d的倍数)
if(isSat(x,k))
k=x-a; return k;
}
int main()
{
scanf("%lld%lld",&a,&b);
printf("%lld\n",Solve()); return ;
}

分割线:2019.7.23

•新想法

  GCD(b-a , a+k) = f(b-a);

  f(b-a) 表示 b-a 的约数;

  当 GCD(b-a,a+k) 确定后,k 越小则 LCM(a+k,b+k) 就越小;

  假设 GCD(b-a,a+k) = f;

  ①如果 a 本身就为 f 的倍数,且 GCD(b-a,a) = f;

  那么 k = 0 是满足当前条件下,使得 LCM(a+k,b+k) 最小的最优解;

  ②反之,如果 a 不为  f 的倍数,那么,找到 ≥ a 的最小的 x·f,并判断 GCD(b-a,x·f) ?= f;

    1)如果 GCD(b-a,x·f) = f;

      那么 k = x·f-a 是满足当前条件下,使得 LCM(a+k,b+k) 最小的最优解;

    2)如果 GCD(b-a,x·f) ≠ f;

      那么 GCD(b-a,(x+1)·f)一定等于 f;

  GCD(b-a,x·f) = GCD(y·f,x·f) = f·GCD(x,y);

  判断 GCD(b-a,x·f) ?= f ⇔ 判断 GCD(y,x) ?= 1;

  如果 GCD(y,x) ≠ 1,那么一定有 GCD(y,x+1) = 1;

•Code

 #include<bits/stdc++.h>
using namespace std;
#define GCD(a,b) __gcd(a,b)
#define ll long long ll a,b; ll g(ll k)
{
return (a+k)/GCD(a+k,b+k)*(b+k);
}
void update(ll f,ll &k)
{
ll x=a/f+(a%f != );///找到使得x·f ≥ a的最小的x
ll y=(b-a)/f; if(GCD(x,y) != )
x++; ///判断是否更新k
ll cur=x*f-a;
if(k == - || g(k) > g(cur))
k=cur;
else if(g(k) == g(cur))
k=min(k,cur);
}
ll Solve()
{
if(a == b)
return ;
if(b < a)
swap(a,b); ll k=-; for(ll i=;i*i <= b-a;++i)
{
if((b-a)%i != )
continue; update(i,k);
update((b-a)/i,k);
} return k;
}
int main()
{
scanf("%lld%lld",&a,&b);
printf("%lld\n",Solve()); return ;
}

      

Codeforces Round #554 (Div. 2) C. Neko does Maths(数学+GCD)的更多相关文章

  1. Codeforces Round #554 (Div. 2) C. Neko does Maths (简单推导)

    题目:http://codeforces.com/contest/1152/problem/C 题意:给你a,b, 你可以找任意一个k     算出a+k,b+k的最小公倍数,让最小公倍数尽量小,求出 ...

  2. Codeforces Round #554 (Div. 2) C.Neko does Maths (gcd的运用)

    题目链接:https://codeforces.com/contest/1152/problem/C 题目大意:给定两个正整数a,b,其中(1<=a,b<=1e9),求一个正整数k(0&l ...

  3. Codeforces Round #554 (Div. 2) C. Neko does Maths (数论 GCD(a,b) = GCD(a,b-a))

    传送门 •题意 给出两个正整数 a,b: 求解 k ,使得 LCM(a+k,b+k) 最小,如果有多个 k 使得 LCM() 最小,输出最小的k: •思路 时隔很久,又重新做这个题 温故果然可以知新❤ ...

  4. Codeforces Round #554 (Div. 2) 1152B. Neko Performs Cat Furrier Transform

    学了这么久,来打一次CF看看自己学的怎么样吧 too young too simple 1152B. Neko Performs Cat Furrier Transform 题目链接:"ht ...

  5. Codeforces Round #554 (Div. 2) 1152A - Neko Finds Grapes

    学了这么久,来打一次CF看看自己学的怎么样吧 too young too simple 1152A - Neko Finds Grapes 题目链接:"https://codeforces. ...

  6. Codeforces Round #554 (Div. 2) B. Neko Performs Cat Furrier Transform(思维题+log2求解二进制位数的小技巧)

    传送门 题意: 给出一个数x,有两个操作: ①:x ^= 2k-1; ②:x++; 每次操作都是从①开始,紧接着是② ①②操作循环进行,问经过多少步操作后,x可以变为2p-1的格式? 最多操作40次, ...

  7. Codeforces Round #554 (Div. 2) E Neko and Flashback (欧拉路径 邻接表实现(当前弧优化..))

    就是一欧拉路径 贴出邻接表欧拉路径 CODE #include <bits/stdc++.h> using namespace std; const int MAXN = 100005; ...

  8. Codeforces Round #554 (Div. 2) F2. Neko Rules the Catniverse (Large Version) (矩阵快速幂 状压DP)

    题意 有nnn个点,每个点只能走到编号在[1,min(n+m,1)][1,min(n+m,1)][1,min(n+m,1)]范围内的点.求路径长度恰好为kkk的简单路径(一个点最多走一次)数. 1≤n ...

  9. Codeforce Round #554 Div.2 C - Neko does Maths

    数论 gcd 看到这个题其实知道应该是和(a+k)(b+k)/gcd(a+k,b+k)有关,但是之后推了半天,思路全无. 然而..有一个引理: gcd(a, b) = gcd(a, b - a) = ...

随机推荐

  1. 2.Redis常用命令

    setget 匹配Keykeys *keys na*keys na?e 判断指定的Key是否存在exists key 删除一个或者多个keydel key//删除一个del key1 key2//删除 ...

  2. Android Http请求方法汇总

    [转]  原文 这篇文章主要实现了在Android中使用JDK的HttpURLConnection和Apache的HttpClient访问网络资源,服务端采用python+flask编写,使用Serv ...

  3. Android通过webservice对sqlserver数据库进行操作

    首页在AndroidManifest.xml中添加访问数据库权限 <uses-sdk android:minSdkVersion="7" /> <uses-per ...

  4. Newton迭代法-C++

    牛顿迭代法: 设定x*是方程f(x)=0的根,选取x0作为x*的近似值,过点(x0, f(x0))做曲线f(x)=0的切线L,L的方程y=f(x0)+f'(x0)(x-x0),求出L与x轴焦点的横坐标 ...

  5. var/let/const区别何在??(转载)

    原文地址:http://www.cnblogs.com/liuhe688/p/5845561.html let和const有很多相似之处,先说一说let吧. 1. let添加了块级作用域 我们知道,J ...

  6. Unity3D — — UGUI之简易背包

    Uinity版本:2017.3 最近在学Siki老师的<黑暗之光RPG>教程,由于教程内用的是NGUI实现,而笔者本人用的是UGUI,所以在这里稍微写一下自己的实现思路(大致上和NGUI一 ...

  7. GRUB 启动 WIN PE 镜像(ISO)

    我用的这个WIN PE ISO只有 46M. 再大些的就没试过了. PE ISO 命名为 minipe.iso. 放在第一块硬盘的第二个分区. MENU.LST的内容. title WinPemap ...

  8. POI读取Excel数据保存到数据库,并反馈给用户处理信息(导入带模板的数据)

    今天遇到这么一个需求,将课程信息以Excel的形式导入数据库,并且课程编号再数据库中不能重复,也就是我们需要先读取Excel提取信息之后保存到数据库,并将处理的信息反馈给用户.于是想到了POI读取文件 ...

  9. ubuntu16.04卸载火狐,Amazon

    一.卸载火狐: . dpkg --get-selections |grep firefox .sudo apt-get purge firefox unity-scope-firefoxbookmar ...

  10. [8.16模拟赛] 玩具 (dp/字符串)

    题目描述 儿时的玩具总是使我们留恋,当小皮还是个孩子的时候,对玩具更是情有独钟.小皮是一个兴趣爱好相当广泛且不专一的人,这这让老皮非常地烦恼.也就是说,小皮在不同时刻所想玩的玩具总是会不同,而有心的老 ...