高精GCD TLE 求助
查看原帖
高精GCD TLE 求助
436102
nod1212楼主2023/10/28 23:22
#include<bits/stdc++.h>
using namespace std;
#define wei 1000000000000000000
#define ws 18
#define maxn 2000
typedef long long ll;
ll fm[19];
struct bi{
    ll num[maxn+14];
    ll len;
};
bi z;
void ou(bi x){
    cout<<x.num[x.len];
    for(ll i=x.len-1;i>=1;i--){
        for(ll j=wei/10;j>=1;j/=10){
            //cout<<x.num[i]<<endl;
            putchar(((x.num[i]/j)%10)+'0');
        }
    }
    return;
}
bi ch(bi x){//x*2
    bi an=z;
    an.len=x.len;
    ll jw=0;
    for(int i=1;i<=x.len;i++){
        //cout<<x.num[i]<<endl;
        an.num[i]=(x.num[i]*2+jw)%wei;
        //cout<<x.num[i]*2+jw<<" "<<(x.num[i]*2+jw)%wei<<endl;
        jw=(x.num[i]*2+jw)/wei;
    }
    if(jw>0){
        an.num[++an.len]=jw;
    }
    //cout<<an.len<<" "<<an.num[an.len]<<endl;
    return an;
}
bi di(bi x){//x/2
    bi ans;
    ans.len=x.len;
    ll ys=0;
    if(x.num[x.len]==1){
        ys=wei;
        ans.len--;
    }
    for(int i=ans.len;i>=1;i--){
        ans.num[i]=(x.num[i]+ys)>>1;
        ys=(ll)((x.num[i]+ys)&1)*wei;
    }
    //ou(ans);
    //cout<<endl;
    return ans;
}
bool zc(bi x){//x%2
    return !(x.num[1]&1);
}
bi operator - (bi x,bi y){//x-y

    ll tw=0;
    bi ans=z;
    for(int i=1;i<=x.len;i++){
        if(i>y.len){y.num[i]=0;}
        if(x.num[i]-tw<y.num[i]){
            ans.num[i]=wei+x.num[i]-tw-y.num[i];
            tw=1;
        }
        else{
            ans.num[i]=x.num[i]-tw-y.num[i];
            tw=0;
        }
    }
    for(int i=1;i<=x.len;i++){
        if(ans.num[i]>0){ans.len=i;}
    }
    return ans;
}
bool operator < (bi x,bi y){
    if(x.len!=y.len){return x.len<y.len;}
    for(int i=x.len;i>=1;i--){
        if(x.num[i]!=y.num[i]){return x.num[i]<y.num[i];}
    }
    return false;
}
bi gcd(bi x,bi y){
    bi a=x;
    bi b=y;
    ll c=0;
    bool fla=true;
    while(1){
        //ou(a);
        //cout<<" ";
        //ou(b);
        //cout<<endl;
        if(fla){
            if(a<b){
                swap(a,b);
            }
        }
        fla=true;
        if(b.len<=1&&b.num[1]==0){break;}
        if(zc(a)){
            if(zc(b)){
                a=di(a);
                b=di(b);
                c++;
                fla=false;
            }
            else{
                a=di(a);
            }
        }
        else{
            if(zc(b)){
                b=di(b);
                fla=false;
            }
            else{
                a=a-b;
            }
        }
    }
    //cout<<c<<endl;
    //ou(a);
    for(int i=1;i<=c;i++){
        a=ch(a);
    }
    return a;
}

void ycl(void){
    for(int i=1;i<=maxn;i++){z.num[i]=0;}
    z.len=1;
    fm[0]=1;
    for(int i=1;i<=18;i++){fm[i]=10*fm[i-1];}
    return;
}
bi in(void){
    string a;
    cin>>a;
    ll zw[maxn];
    for(int i=a.length()-1;i>=0;i--){
        zw[a.length()-i]=a[i]-'0';
        //cout<<a.length()-i<<" "<<zw[a.length()-i]<<endl;
    }
    bi ans=z;
    ans.len=(a.length()+ws-1)/ws;
    for(int i=1;i<=a.length();i++){
        ans.num[(i-1)/ws+1]+=zw[i]*fm[(i-1)%ws];
    }
    for(int i=ans.len+1;i<=maxn;i++){
        ans.num[i]=0;
    }
    //ou(ans);
    //cout<<endl;
    return ans;
}
int main(){
    ycl();
    ou(gcd(in(),in()));
	return 0;
}

思路:使用压位高精,采用更减相损术改进版(即大部分题解中的方法),其中bi表示大整数类型,ch表示自乘2,di表示自除2,已经压了18位,但还是T飞掉

2023/10/28 23:22
加载中...