[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; }