bzoj1876 [SDOI2009]SuperGCD
2017-04-23 19:25
197 查看
传送门
Description
Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约数)!因此他经常和别人比赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个程序来教训他。
Input
共两行: 第一行:一个数A。 第二行:一个数B。
0 < A , B ≤ 10 ^ 10000。
Output
一行,表示A和B的最大公约数。
Sample Input
12
54
Sample Output
6
HINT
Source
Day1
ps:注意压位!
Q:压位以后前导0如何输出?打表?
A:printf有一个神奇的功能,可以在位数不足时在前面补足前导0,我压了9位,所以
CODE:
Description
Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约数)!因此他经常和别人比赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个程序来教训他。
Input
共两行: 第一行:一个数A。 第二行:一个数B。
0 < A , B ≤ 10 ^ 10000。
Output
一行,表示A和B的最大公约数。
Sample Input
12
54
Sample Output
6
HINT
Source
Day1
题解
坑爹的高精GCD,欧几里得定理失效,所以我们要寻求另一种计算GCD的方法:Stein算法。具体可以度娘更相减损术ps:注意压位!
Q:压位以后前导0如何输出?打表?
A:printf有一个神奇的功能,可以在位数不足时在前面补足前导0,我压了9位,所以
printf("%09d",ans[i]);这样写就可以辣!
CODE:
#include<cstdio> #include<iostream> using namespace std; const int N=1e9; int a[10005],b[10005]; char s[10005]; inline int min(int a,int b){return a<b?a:b;} inline void getstring(int &len) { len=-1; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') s[++len]=c,c=getchar(); } inline void read(int *a) { int len; getstring(len); int p=10001; for(int i=len;i>=0;i-=9) { p--; for(int j=min(9,i+1)-1;j>=0;j--) a[p]=a[p]*10+s[i-j]-48; } a[0]=p; } inline bool even(int *a) { if((a[10000]&1)==0) return 1; return 0; } inline void div(int *a) { for(int i=a[0];i<=10000;i++) { if(a[i]&1) a[i+1]+=N; a[i]>>=1; } while(a[a[0]]==0&&a[0]<10000) a[0]++; } inline bool check(int *a) { if(a[0]==10000&&a[10000]==0) return 1; return 0; } inline void del(int *&a,int *&b) { for(int i=10000;i>=a[0];i--) { if(a[i]-b[i]<0) a[i]=a[i]+N-b[i],a[i-1]--; else a[i]-=b[i]; } while(a[a[0]]==0&&a[0]<10000) a[0]++; } inline int cmp(int *a,int *b) { if(a[0]<b[0]) return 1; if(a[0]>b[0]) return -1; for(int i=a[0];i<=10000;i++) { if(a[i]>b[i]) return 1; if(a[i]<b[i]) return -1; } return 0; } inline void mul(int *&a,int k) { while(k--) { int jin=0; for(int i=10000;i>=a[0];i--) { a[i]<<=1;a[i]+=jin; if(a[i]>=N) jin=a[i]/N,a[i]%=N; else jin=0; } if(jin) a[--a[0]]=jin; } } inline void print(int *ans) { for(int i=ans[0];i<=10000;i++) if(i!=ans[0]) printf("%09d",ans[i]); else printf("%d",ans[i]); } inline int *gcd(int *a,int *b) { int k=0; while(even(a)&&even(b)) div(a),div(b),k++; while(!check(a)&&!check(b)) { if(cmp(a,b)==-1) swap(a,b); del(a,b); if(check(a)) break; while(even(a)) div(a); while(even(b)) div(b); if(cmp(a,b)==-1) swap(a,b); } mul(b,k); return b; } int main() { read(a),read(b); print(gcd(a,b)); return 0; }
相关文章推荐
- BZOJ 1876: [SDOI2009]SuperGCD
- 【SDOI2009】【BZOJ1876】SuperGCD
- BZOJ 1876 [SDOI2009] SuperGcd | PY好题
- BZOJ 1876: [SDOI2009]SuperGCD
- BZOJ 1876: [SDOI2009]SuperGCD
- bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)
- BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )
- 【BZOJ】【1876】【SDOI2009】SuperGCD
- bzoj 1876: [SDOI2009]SuperGCD (高精度+gcd)
- [大数GCD Stein算法] BZOJ 1876 [SDOI2009]SuperGCD
- bzoj 1876 [SDOI2009]SuperGCD
- [SDOI2009][BZOJ1876] SuperGCD|高精度|更相减损术
- 【BZOJ 1876】 [SDOI2009]SuperGCD
- BZOJ 1876: [SDOI2009]SuperGCD
- 费用流 模板【SDOI2009】bzoj1877 晨跑
- bzoj 1880 [Sdoi2009]Elaxia的路线(最短路+拓扑序)
- (bzoj 1880 [Sdoi2009]Elaxia的路线)<最短路+拓扑最长链>
- 【bzoj1878】【洛谷P1972】【SDOI2009】HH的项链
- 【BZOJ1875】【矩阵乘法】[SDOI2009]HH去散步
- 【BZOJ 1877】 [SDOI2009]晨跑