[SDOI2009]SuperGCD

题目链接

这题。高精度。恶心。难受。

那么高精度的gcd怎么做呢?

若a=b gcd(a,b)=a

①a偶b偶 gcd(a,b)=2*gcd(a/2,b/2)

②a偶b奇 gcd(a,b)=gcd(a/2,b)

③a奇b奇 gcd(a,b)=gcd(a-b,b)

嗯。这玩意就这样了。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
int a[100000],b[100000],c[100000],f[100000],s0,T,kpl[100000],kyl;
char s[100000];
void bigscanf(int *a){
    scanf("%s",s);
    int len=strlen(s),i,j;
    for(i=0;i<len;++i){
        j=(len-i+3)/4;
        a[j]=a[j]*10+s[i]-'0';
    }
    a[0]=(len+3)/4;
}                                 
void bigprintf(int *a){ 
 cout<<a[a[0]];
 for(int i=a[0]-1;i>0;--i){
     for(int j=1000;j>0;j/=10)cout<<a[i]/j%10;
    }
    cout<<endl;
}                    
int bigcmp(int *a,int *b){ 
    if(a[0]>b[0])return 1;
    if(a[0]<b[0])return -1;
    for(int i=a[0];i>0;i--){
        if(a[i]>b[i])return 1;
        if(a[i]<b[i])return -1;
    }
    return 0;
}
void bigsub(int *a,int *b){
    int k=a[0],g=0;
    for(int i=1;i<=k;i++){                       
        a[i]=a[i]-b[i];
        if(a[i]<0){
            a[i+1]--;
            a[i]=a[i]+10000;
        }
        else g=0;
    }
    while(k>0&&a[k]==0)k--;
    a[0]=k;
}
void bigmul2(int *a,int *b,int *c){
    int k=a[0]+b[0];
    for(int i=1;i<=a[0];i++){
        for(int j=1;j<=b[0];j++){
            c[i+j-1]=c[i+j-1]+a[i]*b[j];
            c[i+j]=c[i+j]+c[i+j-1]/10000;
            c[i+j-1]=c[i+j-1]%10000;
        }
    }
    while(k>0&&c[k]==0)k--;
    c[0]=k;
}
void bigmul1(int *a,int b){
    int k=a[0],g=0;
    for(int i=1;i<=a[0];i++){
        a[i]=a[i]*b+g;
        g=a[i]/10000;
        a[i]=a[i]%10000;
    }
    while(g>0){
        k++;
        a[k]=g%10000;
        g=g/10000;
    }
    while(k>0&&a[k]==0)k--;
    a[0]=k;
}
void bigdiv1(int *a,int b){
    int k=a[0],d=0;
    for(int i=a[0];i>=1;i--){
        d=d*10000+a[i];
        a[i]=d/b;
        d=d%b;
    }
    while(k>0&&a[k]==0)k--;
    a[0]=k;
}
void copy(int *a,int *b){
    for(int i=0;i<=b[0];++i){
        a[i]=b[i];
    }
}
void Gcd(int *a,int *b,int t){
    int u=bigcmp(a,b);//cout<<u<<endl;
    if(u==0){T=t;return;}
    if(u<0){Gcd(b,a,t);return;}
    int ta=0,tb=0;
    if(a[1]%2==0){
        bigdiv1(a,2);
        ta=1;
    }
    if(b[1]%2==0){
        bigdiv1(b,2);
        tb=1;
    }
    if(ta&&tb)Gcd(a,b,t+1);
    else if(! ta&&! tb){bigsub(a,b);Gcd(a,b,t);}
    else Gcd(a,b,t);
}
int main(){
    bigscanf(a);
    bigscanf(b);
    Gcd(a,b,0);
    if(T==0)bigprintf(a);
    else {
        f[0]=f[1]=1;
        for(int i=1;i<=T;i++)bigmul1(f,2);
        bigmul2(f,a,kpl);
        copy(f,kpl);
        bigprintf(f);
    }
return 0;
}

 

posted @ 2019-04-05 15:38  clockwhite  阅读(165)  评论(0编辑  收藏  举报