Logo yyhs_guzicheng的博客

博客

SuperGCD代码

2024-05-28 19:16:08 By yyhs_guzicheng

本质上就是gcd+高精度

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
inline int read()
{
    int x=0;bool t=false;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=true,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return t?-x:x;
}
const ll yw=1000000000000000000;
char ch[11000];
struct BigNum
{
    ll s[800];int ws;
    void output()
        {
            printf("%lld",s[ws]);
            for(int i=ws-1;i;--i)
                printf("%018lld",s[i]);
            puts("");
        }
    void clear(){memset(s,0,sizeof(s));ws=0;}
    void init(char *ch)
        {
            int l=strlen(ch+1);reverse(&ch[1],&ch[l+1]);
            for(int i=1;i<=l;i+=18)
            {
                ++ws;ll ss=1;
                for(int j=0;j<18;++j)
                    if(i+j<=l)s[ws]+=(ch[i+j]-48)*ss,ss*=10;
                    else break;
            }
        }
    void Div2()
        {
            for(int i=ws;i;--i)s[i-1]+=(s[i]&1)*yw,s[i]>>=1;s[0]=0;
            while(!s[ws])--ws;
        }
    void Multi2()
        {
            for(int i=1;i<=ws;++i)s[i]=s[i]<<1;
            for(int i=1;i<=ws;++i)s[i+1]+=s[i]/yw,s[i]%=yw;
            while(s[ws+1])++ws,s[ws+1]+=s[ws]/yw,s[ws]%=yw;
        }
}A,B,One,tmp;
BigNum operator-(BigNum a,BigNum b)
{
    int ws=max(a.ws,1);
    for(int i=1;i<=ws;++i)a.s[i]-=b.s[i];
    for(int i=ws-1;i;--i)if(a.s[i]<0)a.s[i]+=yw,a.s[i+1]-=1;
    while(!a.s[ws])--ws;
    a.ws=ws;return a;
}
bool operator<(BigNum a,BigNum b)
{
    if(a.ws!=b.ws)return a.ws<b.ws;
    for(int i=a.ws;i;--i)
        if(a.s[i]!=b.s[i])return a.s[i]<b.s[i];
    return false;
}int main()
{
    scanf("%s",ch+1);A.init(ch);
    scanf("%s",ch+1);B.init(ch);
    One.s[1]=One.ws=1;int two=0;
    if(B<A)swap(A,B);
    while(233)
    {
        if(A<One)break;
        if(!(A.s[1]&1)&&!(B.s[1]&1))A.Div2(),B.Div2(),++two;
        else if(!(A.s[1]&1))A.Div2();
        else if(!(B.s[1]&1))B.Div2();
        else B=B-A;if(B<A)swap(A,B);
    }
    while(two)B.Multi2(),--two;B.output();
    return 0;
}

评论

dfdf_zhaozekai
#include<bits/stdc++.h> using namespace std; int a[100005],b[100005],c[100005],f[100005],res; const int p=10000; void put(int a[]) { cout<<a[a[0]]; for(int i=a[0]-1;i>0;i--) for(int j=1e3;j>0;j/=10)cout<<a[i]/j%10; } void g(int a[]) { string s; cin>>s; int l=s.size(); for(int i=0;i<l;i++) { int j=(l-i+3)/4; a[j]=a[j]*10+s[i]-'0'; } a[0]=(l+3)/4; } int fk(int a[],int b[]) { if(a[0]>b[0])return 1; if(a[0]<b[0])return -1; for(int i=a[0];i>=1;i--) if(a[i]>b[i])return 1;else if(a[i]<b[i])return -1; return 0; } void div(int a[],int k) { int t=0; for(int i=a[0];i>=1;i--) { t=t*p+a[i]; a[i]=t/k; t%=k; } while(a[a[0]]==0&&a[0]>0)a[0]--; }
dfdf_zhaozekai
void sub(int a[],int b[]) { for(int i=1;i<=a[0];i++) { a[i]-=b[i]; if(a[i]<0)a[i+1]--,a[i]+=p; } while(a[a[0]]==0&&a[0]>0)a[0]--; } void gcd(int a[],int b[],int t) { if(fk(a,b)==0){res=t;return;} if(fk(a,b)<0){gcd(b,a,t);return;} int f1=0,f2=0; if(a[1]%2==0)div(a,2),f1=1; if(b[1]%2==0)div(b,2),f2=1; if(f1&&f2)gcd(a,b,t+1); else if(!f1&&!f2)sub(a,b),gcd(a,b,t); else gcd(a,b,t); }
dfdf_zhaozekai
void mul(int a[],int b[]) { memset(c,0,sizeof(c)); for(int i=1;i<=a[0];i++) for(int j=1;j<=b[0];j++) { c[i+j-1]+=a[i]*b[i]; c[i+j]+=c[i+j-1]/p; c[i+j-1]%=p; } c[0]=a[0]+b[0]; while(c[c[0]]==0&&c[0]>0)c[0]--; memmove(a,c,sizeof(a)); } void mow(int a[],int k) { for(int i=1;i<=a[0];i++)a[i]*=k; for(int i=1;i<=a[0];i++)a[i+1]+=a[i]/p,a[i]%=p; while(a[a[0]+1]>0)a[0]++,a[a[0]+1]=a[a[0]]/p,a[a[0]]%=p; } void fuck() { g(a); g(b); gcd(a,b,0); if(res==0)put(a); else { f[0]=f[1]=1; for(int i=1;i<=res;i++)mow(f,2); mul(f,a); put(f); } } int main() { fuck(); }
dfdf_zhaozekai
P809 70分 SuperGCD 40分 求调试
dfdf_zhaozekai
书上的
dfdf_zhaozekai
@yyhs_guzicheng
yyhs_zhanweijie
@yyhs_guzicheng 太强力qwq
dfdf_zhaozekai
@yyhs_guzicheng 求救
dfdf_zhaozekai
114514114514 2000002 输出00002