您的位置:首页 > 其它

1876: [SDOI2009]SuperGCD

2016-08-22 10:21 381 查看

1876: [SDOI2009]SuperGCD

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 2714  Solved: 917

[Submit][Status][Discuss]

Description

Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个程序来教训他。

Input

共两行: 第一行:一个数A。 第二行:一个数B。

Output

一行,表示A和B的最大公约数。

Sample Input

12

54

Sample Output

6

HINT

对于20%的数据,0 < A , B ≤ 10 ^ 18。

对于100%的数据,0 < A , B ≤ 10 ^ 10000。

Source

Day1

[Submit][Status][Discuss]


高精度GCD,使用更相减损法

10^10000 近似看成2^40000

更相减损法时,若遇到一奇一偶,那个偶数是可以直接除以二,不影响结果

处理的时候每10位数缩成一个高精度位,减小常数





记得输出要有前导0。。。日

一开始还重载错,,死循环#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;

const int maxn = 1E3 + 10;
typedef long long LL;
const LL T = 1E10;
const LL two = 2;

struct data{
int len; LL a[maxn];
data() {len = 0; memset(a,0,sizeof(a));}
data operator - (const data &b) {
for (int i = 1; i <= len; i++)
if (a[i] >= b.a[i]) a[i] -= b.a[i];
else a[i] = a[i] + T - b.a[i],--a[i+1];
for (int i = len; ; i--)
if (a[i]) {len = i; break;}
}
data operator / (const LL &b) {
for (int i = len; i; i--)
a[i-1] += a[i]%b*T,a[i] /= b;
len = a[len]?len:len-1;
}
data operator * (const LL &b) {
for (int i = 1; i <= len; i++)
a[i] *= b,a[i+1] += a[i]/T,a[i] %= T;
if (a[len+1]) ++len;
}
data operator * (const data &b) {
data c;
for (int i = 1; i <= len; i++)
for (int j = 1; j <= b.len; j++) {
c.a[i+j-1] += a[i]*b.a[j];
c.a[i+j] += c.a[i+j-1]/T;
c.a[i+j-1] %= T;
}
for (int i = len + b.len; ; i--)
if (c.a[i]) {c.len = i; break;}
return c;
}
bool operator < (const data &b) const {
if (len < b.len) return 1;
if (len > b.len) return 0;
for (int i = len; i; i--) {
if (a[i] < b.a[i]) return 1;
if (a[i] > b.a[i]) return 0;
}
return 0;
}
bool operator == (const data &b) const {
if (len != b.len) return 0;
for (int i = len; i; i--)
if (a[i] != b.a[i]) return 0;
return 1;
}
}A,B,C;

char aa[maxn*10],bb[maxn*10];
int lena,lenb;

void print(LL now,int tot)
{
if (tot == 10) {printf("%lld",now); return;}
LL Now = now % 10LL;
print(now / 10LL,tot+1);
printf("%lld",Now);
}

int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif

C.a[1] = 1; C.len = 1;
scanf("%s",aa + 1); lena = strlen(aa + 1);
scanf("%s",bb + 1); lenb = strlen(bb + 1);
int tot = 0; LL now = 0;
for (int i = lena; ; i -= 10) {
++tot; now = 0;
if (i <= 10) {
for (int j = 1; j <= i; j++) now = now*10LL + 1LL*(aa[j] - '0');
A.a[tot] = now; A.len = tot; break;
}
for (int j = i - 9; j <= i; j++) now = now*10LL + 1LL*(aa[j] - '0');
A.a[tot] = now;
}

tot = now = 0;
for (int i = lenb; ; i -= 10) {
++tot; now = 0;
if (i <= 10) {
for (int j = 1; j <= i; j++) now = now*10LL + 1LL*(bb[j] - '0');
B.a[tot] = now; B.len = tot; break;
}
for (int j = i - 9; j <= i; j++) now = now*10LL + 1LL*(bb[j] - '0');
B.a[tot] = now;
}

if (A == B) {
printf("%lld",A.a[A.len]);
for (int i = A.len - 1; i; i--) print(A.a[i],1);
return 0;
}

for (;;) {
while (A.a[1] % two == 0 && B.a[1] % two == 0) {A / 2; B / 2; C * 2;}
while (A.a[1] % two == 0) A / 2;
while (B.a[1] % two == 0) B / 2;
if (A == B) {
A = A*C;
printf("%lld",A.a[A.len]);
for (int i = A.len - 1; i; i--) print(A.a[i],1);
return 0;
}
if (A < B) B - A; else A - B;
if (A == B) {
A = A*C;
printf("%lld",A.a[A.len]);
for (int i = A.len - 1; i; i--) print(A.a[i],1);
return 0;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: