传送门

非常显du然liu的一道题

就是求GCD

因为数据范围...

所以要上压位高精+非递归的辗转相减

关于辗转相减:

如果 A是二的倍数,B是二的倍数   那么GCD(A,B)=2 * GCD(A,B)

如果只有A是二的倍数   那么GCD(A,B)=GCD(A/2,B)

如果只有B是二的倍数   那么GCD(A,B)=GCD(A,B/2)

十分显然的结论...

然后不停地让大的数减去小的数

最后当它们相等时就是GCD了(因为大的减小的一直减到不能减就相当于取模)

  1. int slove()
  2. {
  3. int A=read(),B=read(),i=,j=;
  4. while(!(A&)) A>>=,i++;
  5. while(!(B&)) B>>=,j++;
  6. //先把A,B都除成奇数
  7. //这样之后辗转相减时就不会出现两个数都是偶数的情况了
  8. //可以减少判断次数
  9. int cnt=min(i,j);
  10. while()
  11. {
  12. if(A<B) swap(A,B);
  13. if(A==B) return A<<cnt;
  14. A=A-B;
  15. while(!(A&)) A>>=;
  16. }
  17. }

普通的辗转相减法

然后就是恶心的压位高精了...

可以发现我们高精乘除都只乘除2,所以只要写高精乘2和高精除2以及高精减法就好了

重载运算符和压位都是基本操作了

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<cstring>
  6. using namespace std;
  7. typedef long long ll;
  8. const ll wid=;
  9. char ch[];
  10. struct bigint
  11. {
  12. ll s[],len;
  13. bigint() { memset(s,,sizeof(s)); len=; }
  14. inline void read()
  15. {
  16. scanf("%s",ch+);
  17. int l=strlen(ch+),t=,k=; len=(l+)/;
  18. for(int i=l;i;i--)
  19. {
  20. if(!(l-i)%){ k=; t++; }
  21. s[t]+=k*(ch[i]^); k*=;
  22. }
  23. }
  24. inline void print()
  25. {
  26. if(!len) { printf("0\n"); return; }
  27. printf("%lld",s[len]);
  28. for(int i=len-;i;i--) printf("%08lld",s[i]);//除了第一位不足的位用0补
  29. printf("\n");
  30. }
  31. inline bool operator < (const bigint &tmp) const {
  32. if(len!=tmp.len) return len<tmp.len;
  33. for(int i=tmp.len;i;i--) if(s[i]!=tmp.s[i]) return s[i]<tmp.s[i];
  34. return ;
  35. }
  36. inline bool operator == (const bigint &tmp) const {
  37. return !(tmp<*this)&&!(*this<tmp);
  38. }
  39. inline bigint operator - (const bigint &tmp) const {
  40. bigint u; u.len=len;
  41. for(int i=;i<=len;i++)
  42. {
  43. u.s[i]+=s[i]-tmp.s[i];
  44. if(u.s[i]<) u.s[i]+=wid,u.s[i+]--;
  45. }
  46. while(!u.s[u.len]&&u.len) u.len--;
  47. return u;
  48. }
  49. inline bool pd(){ return s[]&; }//判断奇偶
  50. inline void div2()//除2
  51. {
  52. len+=;
  53. for(int i=len;i;i--)
  54. {
  55. if(s[i]&) s[i-]+=wid;
  56. s[i]>>=;
  57. }
  58. while(!s[len]&&len) len--;
  59. }
  60. inline void mul2()//乘2
  61. {
  62. for(int i=;i<=len;i++) s[i]*=;
  63. len+=;
  64. for(int i=;i<=len;i++)
  65. {
  66. s[i+]+=s[i]/wid;
  67. s[i]%=wid;
  68. }
  69. while(!s[len]&&len) len--;
  70. }
  71. }a,b;
  72.  
  73. void slove()
  74. {
  75. int i=,j=;
  76. while(!a.pd()) a.div2(),i++;
  77. while(!b.pd()) b.div2(),j++;
  78. if(i>j) i=j;
  79. while()
  80. {
  81. if(a<b) swap(a,b);
  82. if(a==b) break;
  83. a=a-b;
  84. while(!a.pd()) a.div2();
  85. }
  86. for(int k=;k<=i;k++) a.mul2();
  87. a.print();
  88. }
  89.  
  90. int main()
  91. {
  92. a.read(); b.read();
  93. slove();
  94. return ;
  95. }

P2152 [SDOI2009]SuperGCD的更多相关文章

  1. P2152 [SDOI2009]SuperGCD 未完成

    辗转相减求a,b的gcd其实可以优化的: 1.若a为偶数,b为奇数:gcd(a,b)=gcd(a/2,b) 2.若a为奇数,b为偶数:gcd(a,b)=gcd(a,b/2) 3.若a,b都是偶数:gc ...

  2.  P2152 [SDOI2009]SuperGCD (luogu)

    Stein算法是一种计算两个数最大公约数的算法,是针对欧几里德算法在对大整数进行运算时,需要试商导致增加运算时间的缺陷而提出的改进算法. 算法思想: 由J. Stein 1961年提出的Stein算法 ...

  3. 洛谷 P2152 [SDOI2009]SuperGCD (高精度)

    这道题直接写了我两个多小时-- 主要是写高精度的时候还存在着一些小毛病,调了很久 在输入这一块卡了很久. 然后注意这里用while的形式写,不然会炸 最后即使我已经是用的万进制了,但是交上去还是有两个 ...

  4. 洛谷 P2152 [SDOI2009]SuperGCD

    题意简述 求两个整数a,b的最大公约数0 < a , b ≤ 10 ^ 10000. 题解思路 如果 a % 2 == 0 && b % 2 == 0 gcd(a,b) = gc ...

  5. BZOJ 1876: [SDOI2009]SuperGCD

    1876: [SDOI2009]SuperGCD Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3060  Solved: 1036[Submit][St ...

  6. bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)

    1876: [SDOI2009]SuperGCD Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2384  Solved: 806[Submit][Sta ...

  7. BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )

    更相减损,要用高精度.... --------------------------------------------------------------- #include<cstdio> ...

  8. 【BZOJ1876】[SDOI2009]SuperGCD(数论,高精度)

    [BZOJ1876][SDOI2009]SuperGCD(数论,高精度) 题面 BZOJ 洛谷 题解 那些说数论只会\(gcd\)的人呢?我现在连\(gcd\)都不会,谁来教教我啊? 显然\(gcd\ ...

  9. [BZOJ1876][SDOI2009]superGCD(高精度)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1876 分析: 以为辗转相减会TLE呢……但是好像没这个数据……就这么水过去了…… 辗转 ...

随机推荐

  1. Android SDK和NDK

    NDK是用来给安卓手机开发软件用的,但是和SDK不同的是它用的是C语言,而SDK用的是Java语言.NDK开发的软件在安卓的环境里是直接运行的,一般只能在特定的CPU指令集的机器上运行,而且C语言可以 ...

  2. [原创]Java给word中的table赋值

    一.准备工作: 下载PageOffice for  Java:http://www.zhuozhengsoft.com/dowm/ 二. 实现方法: 要调用PageOffice操作Word中的tabl ...

  3. k8s-集群状态及部署一个实例

    [root@k8s-master ~]# kubectl get csNAME STATUS MESSAGE ERRORcontroller-manager Healthy ok scheduler ...

  4. inteliji ---idea 如何创建scala程序配置

    首先创建一个新的工程: #####################################################################################

  5. ACM学习历程——UVA442 Matrix Chain Multiplication(栈)

    Description   Matrix Chain Multiplication  Matrix Chain Multiplication  Suppose you have to evaluate ...

  6. WC2017 冬眠记

    2017年2月3日,为期7天的冬眠营冬令营正式开幕. 前4天我们见到了各种集训队dalao们的华丽身姿 感受到了听课听不懂睡觉又惭愧的无力感 见到了几百号人近一半玩手机,剩下的一半有一半在睡觉,再剩下 ...

  7. 【Python】numpy 数组拼接、分割

    摘自https://docs.scipy.org 1.The Basics 1.1 numpy 数组基础 NumPy’s array class is called ndarray. ndarray. ...

  8. C# 深化基本概念

    关于IDisposable的Dispose方法 .Net中GC会自动回收托管资源, 对于非托管资源应该使用Dispose方法. 在使用Dispose方法时,应注意避免在Dispose内部中继续释放托管 ...

  9. js中关于事件捕获与事件冒泡的小实验

    1.事件冒泡:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发. IE 5.5: div -> body -> document IE 6.0: div - ...

  10. HDU-5974

    A Simple Math Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Ot ...