bzoj1876: [SDOI2009]SuperGCD

时间:2022-04-15 19:43:20

更相减损数。

上手就debug了3个小时,直接给我看哭了。

3个函数都写错了是什么感受?

乘2函数要从前往后乘,这样后面的数乘2进位以后不会干扰前面的数。

除2函数要从后往前除,这样前面的数借来的位不会除2次。

然后函数里面俩个类里面的变量名不要打混。

哭瞎

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxl = 2000 + 10;
const int d[]={10000000,1,10,100,1000,10000,100000,1000000};
char s[20010];
int cnt; struct bigint {
int a[maxl],len; int& operator [] (int x) {
return a[x];
} void init(char s[]) {
int n=strlen(s+1);
len=(n+7)/8;
for(int i=1,t,e;i<=n;i++) {
e=i%8;
t=(i+7)/8;
a[t]+=(s[n-i+1]-'0')*d[e];
}
} void print() {
printf("%d",a[len]);
for(int i=len-1;i>=1;i--) printf("%08d",a[i]);
printf("\n");
} void div() {
for(int i=1;i<=len;i++) {
if(a[i]&1) a[i-1]+=50000000;
a[i]/=2;
}
if(a[len]==0) len--;
a[0]=0;
} void mul() {
for(int i=len;i>0;i--) {
a[i]<<=1;
a[i+1]+=a[i]/100000000;
a[i]%=100000000;
}
while(a[len+1]) len++;
} bigint operator - (bigint b) {
bigint c;
for(int i=1;i<=len;i++) {
c[i]+=a[i]-b[i];
if(c[i]<0) {c[i]+=100000000; c[i+1]--;}
}
c.len=len;
while(!c[c.len] && c.len) c.len--;
return c;
} bool operator < (bigint b) {
if(len != b.len) {
if(len > b.len ) return 0;
else return 1;
} for(int i=len;i>=1;i--) {
if(a[i] != b[i]) {
if(a[i]<b[i]) return 1;
else return 0;
}
}
return 0;
} bigint() {
memset(a,0,sizeof(a));
len=0;
}
}a,b; int main() {
scanf("%s",s+1);
a.init(s);
scanf("%s",s+1);
b.init(s);
cnt=0;
while(1) {
while(!(a[1]&1) && !(b[1]&1)) {cnt++; a.div(); b.div();}
while(!(a[1]&1)) a.div();
while(!(b[1]&1)) b.div(); if(b<a) a=a-b;
else {
b=b-a;
if(b.len==0) {
while(cnt--) a.mul();
a.print();
break;
}
}
}
return 0;
}