1. 程式人生 > 其它 >一些高精

一些高精

typedef unsigned long long ull;
const int maxl=1e4+3;
const ull base=1000000000;
struct larnum{
    ull dis[maxl];
    larnum(){};
    larnum(ull x){
        if(!x){memset(dis,0,sizeof(dis)),dis[0]=1;return;}
        int i=0;
        while(x>0)dis[++i]=x%base,x/=base;
        dis[0]=i;
    }
    inline void read(){
        memset(dis,0,sizeof(dis));
        char s[maxl];
        scanf("%s",s+1);
        int len=strlen(s+1);
        for(reg i=len;i>=1;i-=9){
            int j=max(i-8,1);
            ull sum=0;
            while(j<=i)sum=(sum<<1)+(sum<<3)+(s[j++]^48);
            dis[++dis[0]]=sum;
        }
    }
    friend larnum operator +(const larnum &a,const larnum &b){
        larnum c(0);
        int len=max(a.dis[0],b.dis[0]);
        for(reg i=1;i<=len;++i){
            c.dis[i]+=a.dis[i]+b.dis[i];
            if(c.dis[i]>=base)
                c.dis[i+1]+=c.dis[i]/base,
                c.dis[i]%=base;
        }
        c.dis[0]=len;
        while(c.dis[c.dis[0]])c.dis[0]++;
        while(!c.dis[c.dis[0]]&&c.dis[0]>1)c.dis[0]--;
        return c;
    }
    friend larnum operator *(const larnum &a,const larnum &b){
        larnum c(0);
        for(reg i=1;i<=a.dis[0];++i)
            for(reg j=1;j<=b.dis[0];++j)
                c.dis[i+j-1]+=a.dis[i]*b.dis[j],
                c.dis[i+j]+=c.dis[i+j-1]/base,c.dis[i+j-1]%=base;
        c.dis[0]=a.dis[0]+b.dis[0];
        while(c.dis[c.dis[0]])c.dis[0]++;
        while(!c.dis[c.dis[0]]&&c.dis[0]>1)c.dis[0]--;
        return c;
    }
    larnum operator *(const ull &a)const{
        larnum c(0);
        for(reg i=1;i<=dis[0];++i){
            c.dis[i]+=dis[i]*a;
            if(c.dis[i]>=base)
                c.dis[i+1]+=c.dis[i]/base,
                c.dis[i]%=base;
        }
        c.dis[0]=dis[0];
        while(c.dis[c.dis[0]])c.dis[0]++;
        while(!c.dis[c.dis[0]]&&c.dis[0]>1)c.dis[0]--;
        return c;
    }
    larnum operator /(const ull &a)const{
        larnum c(0);
        ull res=0;
        for(reg i=dis[0];i;--i){
            ull k=res*base+dis[i];
            c.dis[i]=k/a,res=k%a;
        }
        c.dis[0]=dis[0];
        while(!c.dis[c.dis[0]]&&c.dis[0]>1)c.dis[0]--;
        return c;
    }
    ull operator %(const ull &a)const{
        ull c=0;
        for(reg i=dis[0];i;--i)
            c=(c*base+dis[i])%a;
        return c;
    }
    inline void print()const{
        printf("%llu",dis[dis[0]]);
        for(reg i=dis[0]-1;i;--i)
            printf("%09llu",dis[i]);
    }
};
inline larnum qpow(larnum a,int b){
    larnum ans(0);
    ans.dis[0]=ans.dis[1]=1;
    for(;b;b>>=1,a=a*a)
        if(b&1)ans=ans*a;
    return ans;
}