BZOJ 1876: [SDOI2009]SuperGCD
1876: [SDOI2009]SuperGCD
Time Limit: 4 Sec Memory Limit: 64 MB
Submit: 3060 Solved: 1036
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
54
Sample Output
HINT
对于20%的数据,0 < A , B ≤ 10 ^ 18。
对于100%的数据,0 < A , B ≤ 10 ^ 10000。
Source
首先普通的GCD显然是不行的,而高精度又难以进行mod运算(至少我不会写),所以我们需要一个神奇的求最大公约数的方法。
好像是在60年代,某位前辈深感欧几里得算法求GCD的不便,对其进行了改进,适合大整数(大素数)的GCD过程,而且易于理解。
首先,我们需要了解以下知识:
1. GCD(a, b) = k * GCD(a / k, b / k) 其中,k是a和b的一个公因数。
2. GCD(a, b) = GCD(a / k, b) 其中,k仅为a的因数,而非b的因数。
3. GCD(a, b) = GCD(a - b, b) 其中,a大于等于b。
对于知识1和2,当k=2的时候,有:
如果a,b都是偶数,则GCD(a, b) = 2 * GCD(a / 2, b / 2)。
如果a,b中只有一个偶数,则GCD(a, b) = GCD(a / 2, b)。(假设a是偶数)
而*2和/2的运算可以通过位运算快速实现(当然,不这么做也是可以过的)。
#include <bits/stdc++.h> const int siz = ;
const int mod = ; struct Int
{
int num[siz], len; inline Int(void) {
memset(num, , sizeof(num)), len = ;
} inline Int(char *s) {
int l = strlen(s);
len = (l + ) >> ;
memset(num, , sizeof(num));
for (int i = ; i < l; ++i)
(num[(l - i + ) >> ] *= ) += s[i] - ;
} inline friend bool operator < (const Int &a, const Int &b) {
if (a.len != b.len)
return a.len < b.len;
for (int i = a.len; i; --i)
if (a.num[i] != b.num[i])
return a.num[i] < b.num[i];
return false;
} inline void sub(const Int &a) {
for (int i = ; i <= a.len; ++i)
num[i] -= a.num[i];
for (int i = ; i <= len; ++i)
if (num[i] < )
num[i] += mod, --num[i + ];
while (len > && !num[len])--len;
} inline void mul2(void) {
for (int i = ; i <= len; ++i)
num[i] <<= ;
for (int i = ; i <= len; ++i)
if (num[i] >= mod)
num[i] -= mod, ++num[i + ];
while (num[len + ])++len;
} inline void div2(void) {
for (int i = len; i; --i) {
if (i > && (num[i] & ))
num[i - ] += mod;
num[i] >>= ;
}
while (len > && !num[len])--len;
} inline bool even(void) {
return !(num[] & );
} inline bool zero(void) {
return len == && !num[];
} inline void print(void) {
printf("%d", num[len]);
for (int i = len - ; i; --i)
printf("%08d", num[i]);
putchar('\n');
}
}; inline Int gcd(Int a, Int b)
{
int bit = ;
while (true)
{
if (a.zero()) {
while (bit--)b.mul2();
return b;
}
if (b.zero()) {
while (bit--)a.mul2();
return a;
}
int flag = ;
if (a.even())++flag, a.div2();
if (b.even())++flag, b.div2();
if (flag == )
++bit;
else {
if (a < b)
b.sub(a);
else
a.sub(b);
}
}
} char a[];
char b[]; signed main(void)
{
scanf("%s", a);
scanf("%s", b);
gcd(Int(a), Int(b)).print();
}
@Author: YouSiki
BZOJ 1876: [SDOI2009]SuperGCD的更多相关文章
- bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)
1876: [SDOI2009]SuperGCD Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2384 Solved: 806[Submit][Sta ...
- BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )
更相减损,要用高精度.... --------------------------------------------------------------- #include<cstdio> ...
- BZOJ 1876 [SDOI2009] SuperGcd | PY好题
题面就是让你求两个超级大整数,求GCD 题解: 题目本意应该是出题人想考考高精度取膜 但是可以通过一种神奇的Stein算法来做 由J. Stein 1961年提出的Stein算法很好的解决了欧几里德算 ...
- 【BZOJ1876】[SDOI2009]SuperGCD(数论,高精度)
[BZOJ1876][SDOI2009]SuperGCD(数论,高精度) 题面 BZOJ 洛谷 题解 那些说数论只会\(gcd\)的人呢?我现在连\(gcd\)都不会,谁来教教我啊? 显然\(gcd\ ...
- bzoj 1879: [Sdoi2009]Bill的挑战
题目链接 bzoj 1879: [Sdoi2009]Bill的挑战 题解 n<=15,装压吧 对所有字符串进行装压 可以预处理一个数组can[i][j]表示所有的字符串中,有哪些可以在第i位匹配 ...
- [SDOI2009][BZOJ 1876]SuperGCD
Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比 赛计算GCD.有一天Sheng bill很嚣张地找到了你,并 ...
- bzoj千题计划288:bzoj1876: [SDOI2009]SuperGCD
http://www.lydsy.com/JudgeOnline/problem.php?id=1876 高精压位GCD 对于 GCD(a, b) a>b 若 a 为奇数,b 为偶数,GCD ...
- BZOJ 1876 SuperGCD
Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约数)!因此他经常和别人比赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求 ...
- 「BZOJ 1876」「SDOI 2009」SuperGCD「数论」
题意 求\(\gcd(a, b)\),其中\(a,b\leq10^{10000}\) 题解 使用\(\text{Stein}\)算法,其原理是不断筛除因子\(2\)然后使用更相减损法 如果不筛\(2\ ...
随机推荐
- JavaScript数组方法reduce解析
Array.prototype.reduce() 概述 reduce()方法是数组的一个实例方法(共有方法),可以被数组的实例对象调用.reduce() 方法接收一个函数作为累加器(accumulat ...
- iOS开发中常用的设计模式
常用的设计模式(一)代理模式应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现.优势:解耦合敏捷原则:开放-封闭原则实例:tableview的 数据源delegate,通过 ...
- 阶段一:用Handler和Message实现计时效果及其中一些疑问
“阶段一”是指我第一次系统地学习Android开发.这主要是对我的学习过程作个记录. 本来是打算继续做天气预报的优化的,但因为某些原因,我要先把之前做的小应用优化一下.所以今天就插播一下用Handle ...
- RunLoop 总结:RunLoop的应用场景(二)
上一篇讲了使用RunLoop保证子线程的长时间存活,而不是执行完任务后就立刻销毁的应用场景.这一篇就讲述一下RunLoop如何保证NSTimer在视图滑动时,依然能正常运转. 参考资料 好的书籍都是值 ...
- android ImageLoader 混淆加载drawable出现黑色图片的解决方案
在网上找了很久,没有找到.后来看了源码才知道... 多线程异步加载和显示图片(图片来源于网络.sd卡.assets文件夹,drawable文件夹(不能加载9patch),新增加载视频缩略图) Stri ...
- 优化SQLServer--表和索引的分区(二)
简介 之前一篇简单的介绍了语法和一些基本的概念,隔了一段时间,觉得有必要细致的通过实例来总结一下这部分内容.如之前所说,分区就是讲大型的对象(表)分成更小的块来管理,基本单位是行.这也就产生了很大优势 ...
- mysql查询本周、月、季度、年
#查询本周记录 select * from product_process where WEEKOFYEAR(update_time)=WEEKOFYEAR(now()); #查询本月数据 selec ...
- [数据科学] 从text, json文件中提取数据
文本文件是基本的文件类型,不管是csv, xls, json, 还是xml等等都可以按照文本文件的形式读取. #-*- coding: utf-8 -*- fpath = "data/tex ...
- Java并发之原子变量和原子引用与volatile
我们知道在并发编程中,多个线程共享某个变量或者对象时,必须要进行同步.同步的包含两层作用:1)互斥访问(原子性):2)可见性:也就是多个线程对共享的变量互斥地访问,同时线程对共享变量的修改必须对其他线 ...
- CentOS中的环境变量配置文件
CentOS的环境变量配置文件体系是一个层级体系,这与其他多用户应用系统配置文件是类似的,有全局的,有用户的,有shell的,另外不同层级有时类似继承关系.下面以PATH变量为例. 1.修改/etc/ ...