【模板】高精度模板(粗

 

拖到现在..整理整理。

 

以下高精度数组都是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++;
    }
}
View Code

高精度乘高精度:( 复杂度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;
}
View Code

关于乘法的优化:使用低精乘法来代替部分的高精乘法,或者,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);
}
View Code

 

 

高精度除以单精度:

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--;
}
View Code

高精度除以高精度:

等遇见了再说(:3_ヽ)_

 

posted @ 2019-11-15 18:07  草丛怪  阅读(190)  评论(0编辑  收藏  举报