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;
}
BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】的更多相关文章
- bzoj千题计划288:bzoj1876: [SDOI2009]SuperGCD
http://www.lydsy.com/JudgeOnline/problem.php?id=1876 高精压位GCD 对于 GCD(a, b) a>b 若 a 为奇数,b 为偶数,GCD ...
- [BZOJ1876][SDOI2009]superGCD(高精度)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1876 分析: 以为辗转相减会TLE呢……但是好像没这个数据……就这么水过去了…… 辗转 ...
- bzoj1876: [SDOI2009]SuperGCD
更相减损数. 上手就debug了3个小时,直接给我看哭了. 3个函数都写错了是什么感受? 乘2函数要从前往后乘,这样后面的数乘2进位以后不会干扰前面的数. 除2函数要从后往前除,这样前面的数借来的位不 ...
- 【BZOJ1876】[SDOI2009]SuperGCD(数论,高精度)
[BZOJ1876][SDOI2009]SuperGCD(数论,高精度) 题面 BZOJ 洛谷 题解 那些说数论只会\(gcd\)的人呢?我现在连\(gcd\)都不会,谁来教教我啊? 显然\(gcd\ ...
- 【学术篇】SDOI2009 SuperGCD
特别说明: 为了避免以后搬家时的麻烦, 这里的文章继续沿用csdn的风格和分类好了~ Emmmm这个题是一道高精度的模板题啊~ 既然是高精度的裸题, 那我们这些懒人当然是选择:用python啦~ 懒癌 ...
- BZOJ 1876: [SDOI2009]SuperGCD
1876: [SDOI2009]SuperGCD Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3060 Solved: 1036[Submit][St ...
- bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)
1876: [SDOI2009]SuperGCD Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2384 Solved: 806[Submit][Sta ...
- bzoj 3287: Mato的刷屏计划 高精水题 && bzoj AC150
3287: Mato的刷屏计划 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 124 Solved: 43[Submit][Status] Desc ...
- BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )
更相减损,要用高精度.... --------------------------------------------------------------- #include<cstdio> ...
随机推荐
- python中如何统计一个类的实例化对象
类中的静态变量 需要通过类名.静态变量名 来修改 :通过对象不能修改 python中如何统计一个类的实例化对象?? class Person: #静态变量count,用于记录类被实例化的次数 coun ...
- Java学习笔记十三:Java中的类和对象
Java中的类和对象 一:什么是对象: 总的来说就是"万物皆对象",客观存在的事物皆为对象.是计算机所关注的具体信息. 对象(object)是一件事.一个物体.一个名词,或可以获得 ...
- Excel学习路径总结
本片涉及从入门到Excel的各个方向,包含众多资料和自己学习的心得,希望您可以仔细阅之: 入门篇: 无论是软件,还是编程,最好的入门就是通过看视频来学习,视频优点为很容易看清楚,手把手教授,不容易 ...
- Qt——信号与槽
自定义槽函数,槽函数可以是任何位置定义的函数(成员函数,静态函数,全局函数),但是槽函数的函数类型要和信号的函数类型一致.
- Unicode控制字符
Unicode控制字符就是特殊的Unicode字符 控制字符转义代码对照表 Unicode-控制字符 LRM RLM ZWJ ZWNJ LRE LRO RLO PDF NADS ...
- 集成activiti到现有项目中
1.在lib中添加相关的jar包 2.找到一个activiti.cfg.xml,若是想用现有的数据库需要配置 <?xml version="1.0" encoding=&qu ...
- 20145202马超 2016-2017-2 《Java程序设计》第四周学习总结
20145202马超 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 继承:打破了封装性 extends 1.提高了代码的复用性. 2.让类与类之间产生了关系 ...
- Android开发——Android手机屏幕适配方案总结
)密度无关像素,单位为dp,是Android特有的单位 Android开发时通常使用dp而不是px单位设置图片大小,因为它可以保证在不同屏幕像素密度的设备上显示相同的效果. /** * dp与px的转 ...
- 【C#】 引用类型
[C#] 引用类型 附图和代码为了便于理解引用类型 public static void RefDemo() { RefClass r1 = new RefClass { Name = "r ...
- Percona-Tookit工具包之pt-mysql-summary
Preface Sometimes we need to collect information of MySQL server as a report when we first ...