【模板】高精度模板(粗
拖到现在..整理整理。
以下高精度数组都是int数组 [0,n) ,a[0]表示个位。
高精度乘单精度:
void mul(int a[],int&len,int b) { int i; for(i=0;i<len;i++)a[i]*=b; for(i=0;i<len;i++) { a[i+1]+=a[i]/10; a[i]%=10; } while(a[len]) { a[len+1]=a[len]/10; a[len]%=10; len++; } }
高精度乘高精度:( 复杂度O(n^2) -> 复杂的选择:FFT)
void mul(int a[],int&lena,int b[],int lenb) { int tmp[maxn]={0},i,j,len; for(i=0;i<lena;i++) for(j=0;j<lenb;j++) tmp[i+j]+=a[i]*b[j]; len=lena+lenb-1; for(i=0;i<len;i++)a[i]=tmp[i]; lena=len; for(i=0;i<lena;i++) { if(a[i]>=10) { a[i+1]+=a[i]/10; a[i]%=10; } } i=lena; while(a[i]>0) { if(a[i]>=10) { a[i+1]+=a[i]/10; a[i]%=10; } i++; } lena=i; }
关于乘法的优化:使用低精乘法来代替部分的高精乘法,或者,FFT。
fft 高精度乘高精度:
#include<bits/stdc++.h> using namespace std; const int maxn=2e6+1e5+50; const double PI=3.14159265359; typedef long long ll; struct comp{ double x,y; comp(double xx=0,double yy=0){x=xx;y=yy;} }; template<typename T> void read(T &x) { char ch; while(!isdigit(ch=getchar())); x=ch-'0'; while(isdigit(ch=getchar()))x=x*10+ch-'0'; } comp operator +(comp a,comp b){return comp(a.x+b.x,a.y+b.y);} comp operator -(comp a,comp b){return comp(a.x-b.x,a.y-b.y);} comp operator *(comp a,comp b){return comp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);} int up; int R[maxn],L; void fft(comp *a,int type) { for(int i=0;i<up;i++) if(i<R[i])swap(a[i],a[R[i]]); for(int mid=1;mid<up;mid<<=1) { comp wn=comp(cos(PI/mid),type*sin(PI/mid)); for(int r=mid<<1,j=0;j<up;j+=r) { comp w(1,0); for(int k=0;k<mid;k++,w=w*wn) { comp x=a[j+k],y=w*a[j+mid+k]; a[j+k]=x+y; a[j+mid+k]=x-y; } } } } comp a[maxn],b[maxn]; char a1[maxn],b1[maxn]; int res[maxn],reslen; void mul(char a1[],char b1[]) { int n,m; n=strlen(a1);m=strlen(b1); for(int i=0;i<n;i++)a[i].x=a1[n-i-1]-'0'; for(int i=0;i<m;i++)b[i].x=b1[m-i-1]-'0'; up=1;L=0; while(up<n+m)up<<=1,L++; for(int i=0;i<up;i++) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1)); fft(a,1);fft(b,1); for(int i=0;i<up;i++)a[i]=a[i]*b[i]; fft(a,-1); for(int i=0;i<up;i++) { res[i]+=(int)(a[i].x/up+0.5); res[i+1]=res[i]/10; res[i]%=10; } if(res[n+m-1])reslen=n+m; else reslen=n+m-1; } int main() { scanf("%s%s",a1,b1); mul(a1,b1); for(int i=reslen-1;i>=0;i--)printf("%d",res[i]);putchar(10); }
高精度除以单精度:
void dev(ll a[],int&lena,int b,int &y) { int i; for(i=lena-1;i>0;i--) { a[i-1]=a[i-1]+(a[i]%b)*10; a[i]=a[i]/b; } y=a[0]%b; a[0]=a[0]/b; while(a[lena-1]==0&&lena)lena--; }
高精度除以高精度:
等遇见了再说(:3_ヽ)_