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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】

發布時間:2023/12/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目

Sheng bill有著驚人的心算能力,甚至能用大腦計算出兩個巨大的數的GCD(最大公約 數)!因此他經常和別人比
賽計算GCD。有一天Sheng bill很囂張地找到了你,并要求和你比 賽,但是輸給Sheng bill豈不是很丟臉!所以你
決定寫一個程序來教訓他。

輸入格式

共兩行: 第一行:一個數A。 第二行:一個數B。
0 < A , B ≤ 10 ^ 10000。

輸出格式

一行,表示A和B的最大公約數。

輸入樣例

12

54

輸出樣例

6

題解

時隔大半年,我回來A這道題啦【當初寫的太BUG了】
求GCD,很容一想到輾轉相除,而高精不好操作取模,這就用到了輾轉相除法的本質:更相減損法

GCD(a,b) = GCD(a,a-b) 【a >b】

然而這樣會T,所以我們還要優化:

GCD(a,b) = 2*GCD(a/2,b/2) 【2|a且2|b】
GCD(a,b) = GCD(a/2,b) 【2|a】
GCD(a,b) = GCD(a,b/2) 【2|b】
GCD(a,b) = GCD(a,a-b) 【a >b】
加上個壓位高精【高精減法,高精除低精,高精乘低精,高精比較】
就可以A了

#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #define LL long long int #define REP(i,n) for (int i = 1; i <= (n); i++) using namespace std; const int maxn = 10005,B = 4,Base = 10000,maxm = 100005,INF = 1000000000; struct NUM{int s[maxn],len;NUM() {memset(s,0,sizeof(s)); len = 0;} }; istream& operator >>(istream& in,NUM& a){string s;in>>s;int temp = 0,t = 1;for (int i = s.length() - 1; i >= 0; i--){temp = temp + t * (s[i] - '0');if (t * 10 == Base) a.s[++a.len] = temp,temp = 0,t = 1;else t *= 10;}if (temp) a.s[++a.len] = temp;return in; } ostream& operator <<(ostream& out,const NUM& a){if (!a.len) out<<0;else {printf("%d",a.s[a.len]);for (int i = a.len - 1; i > 0; i--) printf("%04d",a.s[i]);}return out; } bool check(const NUM& a){return !(a.s[1] & 1);} bool equal(const NUM& a,const NUM& b){if (a.len != b.len) return false;REP(i,a.len) if (a.s[i] != b.s[i]) return false;return true; } bool operator <(const NUM& a,const NUM& b){if (a.len < b.len) return true;if (a.len > b.len) return false;for (int i = a.len; i > 0; i--){if (a.s[i] < b.s[i]) return true;if (a.s[i] > b.s[i]) return false;}return false; } void Half(NUM& a){int carry = 0,temp;for (int i = a.len; i > 0; i--){temp = (a.s[i] + carry * Base) / 2;carry = a.s[i] + carry * Base - temp * 2;a.s[i] = temp;}while (!a.s[a.len]) a.len--; } void Twice(NUM& a){int carry = 0,temp;for (int i = 1; i <= a.len; i++){temp = a.s[i] * 2 + carry;a.s[i] = temp % Base;carry = temp / Base;}while (carry) a.s[++a.len] = carry % Base,carry /= Base; } NUM operator -(const NUM& a,const NUM& b){NUM c; c.len = a.len;int carry = 0,temp;for (int i = 1; i <= a.len; i++){temp = a.s[i] - b.s[i] + carry;if (temp < 0) carry = -1,temp += Base;else carry = 0;c.s[i] = temp;}while (!c.s[c.len]) c.len--;return c; } int main(){NUM A,B; int cnt = 0;cin>>A>>B;while (!equal(A,B)){if (check(A) && check(B)) Half(A),Half(B),cnt++;else if (check(A)) Half(A);else if (check(B)) Half(B);else {if (B < A) swap(A,B);B = B - A;}}while (cnt--) Twice(A);cout<<A<<endl;return 0; }

轉載于:https://www.cnblogs.com/Mychael/p/8282745.html

總結

以上是生活随笔為你收集整理的BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】的全部內容,希望文章能夠幫你解決所遇到的問題。

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