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

更相减损,要用高精度....

---------------------------------------------------------------

#include<cstdio>

#include<cstring>

#include<cctype>

#include<algorithm>

using namespace std;

const int maxn = 10009;

char S[maxn];

int Power[maxn];

struct BigInt {

static const int B = 10000000;

static const int W = 7;

static const int MAXN = 10000;

int n, s[MAXN];

BigInt() {

n = 0;

memset(s, 0, sizeof s);

}

bool operator < (const BigInt &t) const {

if(n != t.n) return n < t.n;

for(int i = n; i--; )

if(s[i] != t.s[i]) return s[i] < t.s[i];

return true;

}

bool operator != (const BigInt &t) const {

return (*this < t) != (t < *this);

}

BigInt operator -= (const BigInt &t) {

for(int i = 0; i < t.n; i++) {

if(s[i] < t.s[i])

s[i] += B, s[i + 1]--;

s[i] -= t.s[i];

}

for(int i = t.n; i < n; i++) if(s[i] < 0)

s[i] += B, s[i + 1]--;

while(n > 0 && !s[n - 1]) n--;

return *this;

}

void Read() {

scanf("%s", S);

int N = strlen(S), p = N; n = N / W;

for(int i = 0; i < n; i++) {

for(int j = p - W; j < p; j++)

s[i] = s[i] * 10 + S[j] - ‘0‘;

p -= W;

}

if(N % W) {

for(int i = 0; i < p; i++)

s[n] = s[n] * 10 + S[i] - ‘0‘;

n++;

}

}

void Write() {

for(int i = n; i--; ) {

if(i != n - 1) {

int t = 0;

for(int v = s[i]; v; v /= 10) t++;

if(!t) t++;

while(t < W)

putchar(‘0‘), t++;

}

printf("%d", s[i]);

}

putchar(‘\n‘);

}

inline bool chk() {

return n == 1 && s[0] == 1;

}

inline bool Even() {

return !(s[0] & 1);

}

void Div2() {

for(int i = n; i--; ) {

if(s[i] & 1)

s[i - 1] += B;

s[i] >>= 1;

}

if(!s[n - 1]) n--;

}

void Mul2() {

for(int i = n; i--; ) s[i] <<= 1;

for(int i = 0; i < n; i++)

if(s[i] >= B) s[i] -= B, s[i + 1]++;

if(s[n]) n++;

}

} A, B, *a = &A, *b = &B;

int main() {

a->Read(); b->Read();

int cnt = 0;

while(*a != *b) {

if(a->chk()) break;

if(a->Even()) {

a->Div2();

if(b->Even()) b->Div2(), cnt++;

} else if(b->Even()) {

b->Div2();

} else {

if(*b < *a) swap(b, a);

*b -= *a;

}

}

while(cnt--) a->Mul2();

a->Write();

return 0;

}

---------------------------------------------------------------

1876: [SDOI2009]SuperGCD

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 2277  Solved: 770
[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

时间: 2024-08-04 09:25:22

BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )的相关文章

[SDOI2009][BZOJ1876] SuperGCD|高精度|更相减损术

1876: [SDOI2009]SuperGCD Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1970  Solved: 663[Submit][Status][Discuss] Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个

【C语言】最大公约数(更相减损法)和(辗转相除法)

#include<stdio.h> #include <math.h> /* 编写一个函数,传入a,b两个int类型的变量,返回两个值的最大公约数. 例如:输入传入(0 , 5)函数返回5,传入(10 , 9)函数返回1,传入(12 , 4)函数返回4 */ //更相减损法 int fuc(int m,int n) { int i=0,temp,x; while(m%2==0 && n%2==0) //判断m和n能被多少个2整除 { m/=2; n/=2; i+=1

C语言复习---获取最大公约数(辗转相除法和更相减损法)

源自:百度百科 辗转相除法 辗转相除法:辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里德算法. 例如,求(319,377): ∵ 319÷377=0(余319) ∴(319,377)=(377,319): ∵ 377÷319=1(余58) ∴(377,319)=(319,58): ∵ 319÷58=5(余29) ∴ (319,58)=(58,29): ∵ 58÷29=2(余0) ∴ (58,29)= 29: ∴ (319,377)=29. 用辗转相除法求几个数的最大公约数,可以先求出

求两个数的最大公约数,辗转相除法与更相减损法(递归迭代)

问题:给出两个数a和b,求出他们的最大公约数(greatest common divisor). 解法一:辗转相除法,又叫欧几里得算法.两个正整数a和b(a>b),他们的最大公约数等于a除以b的余数和b之间的最大公约数. 比如10和25,25除以10余5,那么10和25的最大公约数等同于5和10之间的最大公约数. //辗转相除法 递归解法 int gcd(int a,int b){ if(a%b==0) return b; return (b,a%b); } //辗转相除法 迭代解法int gc

BZOJ 1876: [SDOI2009]SuperGCD

1876: [SDOI2009]SuperGCD Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2999  Solved: 1011[Submit][Status][Discuss] Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一

更相减损术求最大公约数-C

可参照辗转相除 1 #include<stdio.h> 2 3 int main(void) 4 { 5 int x=260; 6 int y=104; 7 8 int temp; //临时变量 9 10 int index=0; 11 while((x%2==0)&&(y%2==0)) 12 { 13 x/=2; 14 y/=2; 15 ++index; 16 } 17 18 while(x!=y) 19 { 20 temp=x-y; 21 if(temp<y) 22

【BZOJ 1876】 [SDOI2009]SuperGCD

1876: [SDOI2009]SuperGCD Time Limit: 4 Sec Memory Limit: 64 MB Submit: 1750 Solved: 560 [Submit][Status][Discuss] Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个

BZOJ1876: [SDOI2009]SuperGCD

1876: [SDOI2009]SuperGCD Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比 赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你 决定写一个程序来教训他. Input 共两行: 第一行:一个数A. 第二行:一个数B. 0 < A , B ≤ 10 ^ 10000. Output 一行,表示A和B的最大公约数. S

[SDOI2009]SuperGCD

[题面]: [SDOI2009]SuperGCD [思路]: 毒瘤高精.. 考这种题真不知道出题人怎么想的,高精就算了还要压八位..我高精板子都挂了还是寻欢大神给我了个板子\(qwq\) 这是一道裸(du)的(liu)\(GCD\),当你把一切运算符都重载之后,你就可以愉快地\(coding\)出来\(gcd\)!then TLE 你还需要这个:更相减损术 可半者半之,不可半者,副置分母.子之数,以少减多,更相减损,求其等也.以等数约之.\(orz\) 具体来说,就是(如果需要对分数进行约分,那