题目
计算两个大整数的
数据范围:
分析
即写高精形式的
即是更相损减术的优化,对于
首先提取其公共
的幂次,
即
.
由更相损减术,,但这种直接计算若两者差值太大则时间复杂度逼近
(n为最大整数的值).注意到
值为奇数,则可以通过对
中的2的倍数
减半规模.
若则
,否则
,并对
进行可能的折半操作
PS:一开始写的函数(*,&)形式,莫名其妙TLE. ヘ(;′Д`ヘ)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1e4 + 5;
struct big {
int num[MAXN], len;
void init(){
memset(num, 0, sizeof(num));
len = 1;
}
big operator -(const big &a){
big res;
res.init(), res.len = max(len, a.len);
int i;
for(i = 1; i <= res.len; i++){
res.num[i] += num[i] - a.num[i];
while(res.num[i] < 0) res.num[i] += 10, res.num[i + 1]--;
}
while(!res.num[res.len] && res.len > 1) res.len--;
return res;
}
big operator *(const int &x){
int i;
big res;
res.init(), res.len = len;
for(i = 1; i <= len; i++)
res.num[i] = num[i] * x;
for(i = 1; i <= len; i++)
res.num[i + 1] += res.num[i] / 10, res.num[i] %= 10;
while(res.num[++res.len] > 9) res.num[res.len + 1] += res.num[res.len], res.num[res.len] %= 10;
while(!res.num[res.len] && res.len) res.len--;
return res;
}
big operator /(const int &x){
int i;
big res;
res.init(), res.len = len;
for(i = len; i >= 1; i--)
res.num[i] = num[i];
for(i = len; i >= 1; i--)
res.num[i - 1] += res.num[i] % x * 10, res.num[i] /= x;
res.num[0] = 0;
while(!res.num[res.len] && res.len > 1) res.len--;
return res;
}
bool operator <(const big &a){
if(len != a.len) return len < a.len;
int i;
for(i = len; i >= 1; i--)
if(num[i] != a.num[i]) return num[i] < a.num[i];
return false;
}
bool operator==(const big &a){
if(len != a.len) return false;
int i;
for(i = 1; i <= len; i++) if(num[i] != a.num[i]) return false;
return true;
}
void getprint(){
int i;
for(i = len; i >= 1; i--) printf("%d", num[i]); printf("\n");
}
};
big a, b;
char s[MAXN];
big Stein_gcd(big, big);
int main(){
int i;
scanf("%s", s + 1), a.len = strlen(s + 1);
for(i = 1; i <= a.len; i++)
a.num[i] = s[a.len - i + 1] - '0';
scanf("%s", s + 1), b.len = strlen(s + 1);
for(i = 1; i <= b.len; i++)
b.num[i] = s[b.len - i + 1] - '0';
big res = Stein_gcd(a, b);
res.getprint();
return 0;
}
big Stein_gcd(big x, big y){
int i, bit_acc = 0;
while(x.num[1] % 2 == 0 && y.num[1] % 2 == 0)
bit_acc++, x = x / 2, y = y / 2;
while(x.num[1] % 2 == 0) x = x / 2;
while(y.num[1] % 2 == 0) y = y / 2;
while(!(x == y)){
if(x < y) swap(x, y);
x = x - y;
while(x.num[1] % 2 == 0) x = x / 2;
}
while(bit_acc--) x = x * 2;
return x;
}