您的位置:首页 > 其它

bzoj1876: [SDOI2009]SuperGCD

2017-03-07 09:52 369 查看
传送门

哈,不用高精度的做法应该都会吧、

可是要高精度。

于是我们可以将A%B化为A-B^x-……

x为2的幂次。

这样用辗转相除法求出gcd

#include<cstring>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define mo 1000000000
using namespace std;
struct bignum{
ll a[1200];
bool operator <= (bignum x){
if (a[0]!=x.a[0]) return a[0]<x.a[0];
for (int i=a[0];i>=1;i--)
if (a[i]!=x.a[i]) return a[i]<x.a[i];
return 1;
}
void operator *= (ll x){
for (int i=1;i<=a[0];i++) a[i]*=x;
for (int i=1;i<=a[0];i++){
a[i+1]+=a[i]/mo;
a[i]%=mo;
}
if (a[a[0]+1]) a[0]++;
}
void operator /= (ll x){
ll y=0;
for (int i=a[0];i>=1;i--){
y=y*mo+a[i];
a[i]=y/x;
y%=x;
}
if (!a[a[0]]) a[0]--;
}
void operator -= (bignum x){
for (int i=1;i<=a[0];i++) a[i]-=x.a[i];
for (int i=1;i<=a[0];i++)
if (a[i]<0) a[i]+=mo,a[i+1]--;
while (!a[a[0]]&&a[0]) a[0]--;
}
void yw(char *b){
ll x=0;
int len=strlen(b);
for (int i=len;i>0;i--){
if (i%9==0){a[i/9+1]=x; x=0;}
x=x*10+b[len-i]-48;
}
a[1]=x;
a[0]=(len-1)/9+1;
}
void print(){
printf("%d",a[a[0]]);
for (int i=a[0]-1;i>=1;i--) printf("%09d",a[i]);
printf("\n");
}
}c,d;
int j=0;
char a[10005],b[10005];
int main(){
scanf("%s%s",&a,&b);
c.yw(a); d.yw(b);
if (c<=d) swap(c,d);
while (d.a[0]!=0){
while (!(d.a[1]&1)&&!(c.a[1]&1)) d/=2,c/=2,j++;
while (!(d.a[1]&1)) d/=2;
while (!(c.a[1]&1)) c/=2;
if (c<=d) swap(c,d);
c-=d;
if (c<=d) swap(c,d);
}
for (;j>0;j--) c*=2;
c.print();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: