日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【CodeForces - 1152C 】Neko does Maths(数学数论,lcm,gcd性质)

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CodeForces - 1152C 】Neko does Maths(数学数论,lcm,gcd性质) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題干:

給出a,b<=1e9,你要找到最小的k使得lcm(a+k,b+k)盡可能小,如果有多個k給出同樣的最小公倍數,輸出最小的一個k。

解題報告:

因為題目中k太多了,先化簡一下公式,假設a>b ,則gcd(a+k,b+k) == gcd(a+k,a+b);

下面給出一個簡單證明:

z=gcd(a+k,b+k);

?所以:(a+k)%z==0,(b+k)%z==0;

? ?(a+k)%z==(b+k)%z;

? a%z+k%z=b%z+k%z;

故? (a-b)%z=0;

還有個一般化的結論: gcd(a,a) = gcd(a,a)      gcd(a,b) = gcd(a,a-b)(a>b)       gcd(a,b) = gcd(b,a-b)(a>b)

所以公式可以化為:

lcm(a+k,b+k) = (a+k)*(b+k) / gcd(a+k,b+k). 要使得lcm(a+k,b+k)最小,則需要gcd(a+k,b+k)最大

因此只需要枚舉(a-b)的因子將a+k湊至存在該因子fac(即a+k是fac的倍數),求出那個最小的k,(即k =(fac-a%fac)),取lcm最小值即可。

至于為什么k=fac-a%fac呢?下面給出簡要證明:

這是因為首先k<fac,(因為假設k>=fac有上述條件成立,則總可以通過k-=fac的操作使得k變小且原式依舊成立),且k是在這個條件下是唯一的(這個很顯然,不解釋了),所以在模fac的意義下肯定有a+k==0(mod fac),因此k=fac-a%fac,

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e5 + 5; ll a,b; vector<ll> vv; void solve(ll x) {//求出x的所有因子 for(ll i = 1; i*i<=x; i++) {if(x%i == 0) {vv.pb(i);if(i*i!=x) vv.pb(x/i);}} } ll lcm(ll a,ll b) {return a*b/__gcd(a,b); } int main() {cin>>a>>b;if(a < b) swap(a,b);//保證a>bll tmp = a-b,minn = lcm(a,b),ans=0;solve(tmp);int up = vv.size();for(int i = 0; i<up; i++) {ll k = vv[i] - a%vv[i];if(lcm(a+k,b+k) < minn) {minn = lcm(a+k,b+k);ans = k;}} cout << ans << endl;return 0 ; }

?

總結

以上是生活随笔為你收集整理的【CodeForces - 1152C 】Neko does Maths(数学数论,lcm,gcd性质)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。