C. Neko does Maths(数论 二进制枚举因数)

 题目链接:https://codeforces.com/contest/1152/problem/C

题目大意:给你a和b,然后让你找到一个k,使得a+k和b+k的lcm.

学习网址:https://blog.csdn.net/yopilipala/article/details/89517933

具体思路:

 

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define ll long long
 4 # define inf 0x3f3f3f3f
 5 const int maxn = 2e5+100;
 6 vector<ll>sto;
 7 void init(ll t)
 8 {
 9     ll tmp=t;
10     for(ll i=2; i*i<=tmp; i++)
11     {
12         while(t%i==0)
13         {
14             t/=i;
15             sto.push_back(i);
16         }
17     }
18     if(t!=1)
19         sto.push_back(t);
20 }
21 ll cal(int t)
22 {
23     ll ans=1ll;
24     int pos=0;
25     while(t)
26     {
27         if(t&1)
28         {
29             ans=ans*sto[pos];
30         }
31         pos++;
32         t>>=1;
33     }
34     return ans;
35 }
36 int main()
37 {
38     ll a,b;
39     scanf("%lld %lld",&a,&b);
40     if(a==b)
41     {
42         printf("0\n");
43         return 0;
44     }
45     if(a>b)
46         swap(a,b);
47     init(b-a);
48     int maxstate=(1<<(sto.size()))-1;
49     ll minn=(1ll<<60);
50     ll ans=(1ll<<60);
51     for(int i=1; i<=maxstate; i++)
52     {
53         ll tmp=cal(i);
54         ll t1=(a/tmp+1)*tmp;//注意是先除
55         ll t2=(b/tmp+1)*tmp;
56         ll w=t1*t2/__gcd(t1,t2);
57         if(w<=minn)
58         {
59             if(w<minn)
60             {
61                 minn=w;
62                 ans=t1;
63             }
64             else if(w==minn)
65             {
66                 minn=w;
67                 ans=min(ans,t1);
68             }
69         }
70     }
71     ll tmp=a*b/__gcd(a,b);
72     if(tmp<=minn)
73     {
74         minn=tmp;
75         ans=a;
76     }
77     printf("%lld\n",ans-a);
78     return 0;
79 }

 

原文地址:https://www.cnblogs.com/letlifestop/p/10773514.html

时间: 2024-08-30 17:36:38

C. Neko does Maths(数论 二进制枚举因数)的相关文章

51nod 1363 最小公倍数的和 欧拉函数+二进制枚举

1363 最小公倍数之和 题目来源: SPOJ 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 给出一个n,求1-n这n个数,同n的最小公倍数的和.例如:n = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30,6,加在一起 = 66. 由于结果很大,输出Mod 1000000007的结果. Input 第1行:一个数T,表示后面用作输入测试的数的数量.(1 <= T <= 50000) 第2 - T + 1行:T个数A[i](A[i] <

CodeForces-1152C Neko does Maths(GCD)

题目传送门:CodeForces-1152C Neko does Maths 题目大意: 给你两个值a,b,让你求出使lcm(a+k,b+k),最小的k值 gcd性质: gcd性质:gcd(a,a) = gcd(a,a) gcd(a,b) = gcd(a,a-b)(a>b) gcd(a,b) = gcd(b,a-b)(a>b)证明:设gcd(a,b)=z; a=zx ,b=zy ,a-b=z(x-y) 要证明a-b和b的gcd等于a和b的gcd b=zy a-b=z(x-y) 则需要证明y和x

Codeforces Round #554 (Div. 2) 1152C. Neko does Maths

学了这么久,来打一次CF看看自己学的怎么样吧 too young too simple 1152C. Neko does Maths 题目链接:"https://codeforces.com/contest/1152/problem/C" 题目大意:给你两个数a,b,现在要你找出一个数k使得(a+k)和(b+k)的最小公倍数最小. 题目思路:暴力(逃) 这题没得思路,想了想既然求LCM了那么和GCD说不定有点关系 然后就没有然后了 比赛的时候交了一发暴力上去,然并软 赛后补题,题解里面

Codeforces . C.Neko does Maths

题目描述: C. Neko does Maths time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Neko loves divisors. During the latest number theory lesson, he got an interesting exercise from his math teacher. N

UVa 818 切断圆环链(dfs+二进制枚举)

https://vjudge.net/problem/UVA-818 题意:有n个圆环,其中有一些已经扣在了一起.现在需要打开尽量少的圆环,使得所有圆环可以组成一条链,例如,有5个圆环,1-2,2-3,4-5,则需要打开一个圆环,如圆环4,然   后用它穿过圆环3和圆环5后再次闭合4,就可以形成一条链:1-2-3-4-5. 思路:从n个圆环中任意选择圆环,这就是枚举子集.所以这道题目可以用二进制枚举来做. 那么如何判断当前打开圆环是可行的呢?在去除打开的圆环后需要判断: ①:每个圆环的分支数都必

UVa818 Cutting Chains (二进制枚举)

链接:http://vjudge.net/problem/35523 分析:links记录初始圆环链的情况,然后二进制枚举编号为0~n-1的圆环哪个被打开了,一个圆环最多一个前驱和一个后继,所以judge判断如果有一个未打开的圆环同时和2个以上的未打开圆环相连就一定不能形成链,剪去.circle判断剩下的未打开圆环是否形成环,以及若未成环那么有多少条单链links_num,注意最后成链不用按顺序比如1->2->3...这样.然后判断一下打开的圆环数够不够把links_num条单链扣成一条链,若

POJ 2436 二进制枚举+位运算

题意:给出n头牛的得病的种类情况,一共有m种病,要求找出最多有K种病的牛的数目: 思路:二进制枚举(得病处为1,否则为0,比如得了2 1两种病,代号就是011(十进制就是3)),首先枚举出1的个数等于k的二进制数,然后跟所有的牛的代号一一比较,符合的           +1,找出其中和最大的:就是转换2进制麻烦,用位运算就好实现了,但是位运算不是很明白含义,明白了再补充: 知识点: 3 & 2 = 2,相同为1,不同为0, 011 & 010 = 010:(怎么利用的这个特点不明白):

1151 - Buy or Build(二进制枚举子集 + 并查集)

这题LRJ书上翻译的有问题,书上说两点之间的cost是两点的欧几里得距离,而题目要求两点的距离是两点欧几里得距离的平方. 其余就没什么好说的了,裸的并查集,需要注意的就是二进制枚举子集的问题. 二进制枚举子集: for(int i = 0 ; i < (1 << s) ; i++){ /*s是集合元素的个数*/ for(int j = 0 ; j < s ; j++){ if(!(s >> j) & 1) continue; else{ } } } 140548

UvaLive 6661 Equal Sum Sets 二进制枚举/DP

链接:http://vjudge.net/problem/viewProblem.action?id=49406 题意:根据给出的n,k,s求出n个数每个数都不大于k,和为s的序列(n个数每个都不同)的总情况数. 思路: 1.二进制枚举枚举出所有可能排列,并求和若和为s,则符合,否则不符合. 代码: #include<iostream> #include<set> #include<map> #include<queue> #include<cstri