Codeforces Round #554 (Div. 2) C. Neko does Maths(数学+GCD)
•题意
给出两个正整数 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)的更多相关文章
- Codeforces Round #554 (Div. 2) C. Neko does Maths (简单推导)
题目:http://codeforces.com/contest/1152/problem/C 题意:给你a,b, 你可以找任意一个k 算出a+k,b+k的最小公倍数,让最小公倍数尽量小,求出 ...
- 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 ...
- 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: •思路 时隔很久,又重新做这个题 温故果然可以知新❤ ...
- Codeforces Round #554 (Div. 2) 1152B. Neko Performs Cat Furrier Transform
学了这么久,来打一次CF看看自己学的怎么样吧 too young too simple 1152B. Neko Performs Cat Furrier Transform 题目链接:"ht ...
- Codeforces Round #554 (Div. 2) 1152A - Neko Finds Grapes
学了这么久,来打一次CF看看自己学的怎么样吧 too young too simple 1152A - Neko Finds Grapes 题目链接:"https://codeforces. ...
- Codeforces Round #554 (Div. 2) B. Neko Performs Cat Furrier Transform(思维题+log2求解二进制位数的小技巧)
传送门 题意: 给出一个数x,有两个操作: ①:x ^= 2k-1; ②:x++; 每次操作都是从①开始,紧接着是② ①②操作循环进行,问经过多少步操作后,x可以变为2p-1的格式? 最多操作40次, ...
- Codeforces Round #554 (Div. 2) E Neko and Flashback (欧拉路径 邻接表实现(当前弧优化..))
就是一欧拉路径 贴出邻接表欧拉路径 CODE #include <bits/stdc++.h> using namespace std; const int MAXN = 100005; ...
- 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 ...
- 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) = ...
随机推荐
- (五) Keras Adam优化器以及CNN应用于手写识别
视频学习来源 https://www.bilibili.com/video/av40787141?from=search&seid=17003307842787199553 笔记 Adam,常 ...
- Android与js互相调用
有话要说: 本篇主要总结了简单的Android与js互相调用的方法. 在开发过程中遇到了需要在安卓中调用js方法的需求,于是将具体的实现过程总结成这篇博客. 效果: 其中“调用安卓方法”按钮是html ...
- 巧用Handler获取View控件信息
众所周知,在Android实际开发中,对于某些复杂多变的情况,控件的位置摆放.大小控制并非是xml类型的layout文件完全可以搞定的.此时,我们通常会使用Java代码来通过动态计算,将指定的控件摆放 ...
- IPV6地址中的%号什么意思
在我配置ipv6 网络中,会发现ipv6地址后有%号,这表示什么呢? IPv6地址中的百分号是网卡interface标识.这个表示该地址仅限于标号为21的网络接口(一般指网卡或者虚拟网卡).而在其他网 ...
- 调研行为树jbt
最近要做游戏ai,看了一下行为树的东西,因为用的java,所以主要看了jbt: https://github.com/gaia-ucm/jbt 这玩意分编辑器JBTEditor和核心库JBTCore两 ...
- Linux(CentOS7)yum安装卸载命令,离线下载安装包
一.Linux版本 二.yum安装 比如安装vim编辑器,y是自动应答,即默认一路确认,不用中途确认 yum install -y vim 三.yum卸载 比如卸载掉刚刚安装的vim yum eras ...
- java 浅复制 代码
1 类实现Cloneable接口 2 重写clone()方法 3 类变量引用类型无法复制 class Dog extends Pet implements Cloneable{ int c; i ...
- redis 初步认识二(c#调用redis)
前置:服务器安装redis 1.引用redis 2.使用redis(c#) 一 引用redis (nuget 搜索:CSRedisCore) 二 使用redis(c#) using System ...
- Data Protection - how to manage expired key?(转载)
问 According to ASP.NET Key Management: Deleting a key is truly destructive behavior, and consequentl ...
- Golang 入门 : 打造开发环境
工欲善其事,必先利其器!在学习和使用 Golang 时如果有一款得心应手的 IDE,相信一定可以事半功倍.虽然很多 IDE 都提供了对 Golang 的支持,但真正好用的没几个.VSCode 算是不错 ...


