zoukankan      html  css  js  c++  java
  • 模板

    注意这个乘法是两个数长度相加,但是经过你准确的计算可能并不会有这么长,那么就用MAXLEN截断他。

    struct BigInt {
        const static int mod=10000;
        const static int DLEN=4;
        int a[30005],len;
    
        BigInt() {
            memset(a,0,sizeof(a));
            len=1;
        }
    
        BigInt(int v) {
            memset(a,0,sizeof(a));
            len=0;
            do {
                a[len++]=v%mod;
                v/=mod;
            } while(v);
        }
    
        BigInt(const char *s) {
            memset(a,0,sizeof(a));
            int L=strlen(s);
            len = L/DLEN;
            if(L%DLEN)
                len++;
            int index=0;
            for(int i=L-1; i>=0; i-=DLEN) {
                int t=0;
                int k=i-DLEN+1;
                if(k<0)
                    k=0;
                for(int j=k; j<=i; j++)
                    t=t*10+s[j]-'0';
                a[index++] = t;
            }
        }
    
        BigInt operator+(const BigInt &b)const {
            BigInt res;
            res.len=max(len,b.len);
            for(int i=0; i<res.len; i++) {
                res.a[i]+=((i<len)?a[i]:0)+((i<b.len)?b.a[i]:0);
                res.a[i+1]+=res.a[i]/mod;
                res.a[i]%=mod;
            }
            if(res.a[res.len] > 0)
                res.len++;
            return res;
        }
    
        BigInt operator*(const BigInt &b)const {
            BigInt res;
            for(int i=0; i<len; i++) {
                int up = 0;
                for(int j=0; j<b.len; j++) {
                    int temp=a[i]*b.a[j]+res.a[i+j]+up;
                    res.a[i+j]=temp%mod;
                    up=temp/mod;
                }
                if(up != 0)
                    res.a[i+ b.len]=up;
            }
            res.len=len+b.len;
            while(res.a[res.len-1]==0&&res.len>1)
                res.len--;
            return res;
        }
    
        bool operator<(const BigInt &b)const {
            if(len<b.len)
                return true;
            else if(len==b.len) {
                int ln=len-1;
                while(a[ln]==b.a[ln]&&ln>=0)
                    ln--;
                if(ln>=0&&a[ln]<b.a[ln])
                    return true;
                else
                    return false;
            } else
                return false;
        }
    
        bool operator>(const BigInt &b)const {
            return b<*this;
        }
    
        bool operator==(const BigInt &b)const {
            if(len!=b.len)
                return false;
            for(int ln=len-1; ln>=0; ln--)
                if(a[ln]!=b.a[ln])
                    return false;
            return true;
        }
    
        bool operator!=(const BigInt &b)const {
            return !(*this==b);
        }
    
        void output() {
            printf("%d",a[len-1]);
            for(int i = len-2; i >=0 ; i--)
                printf("%04d",a[i]);
            printf("
    ");
        }
    };
    

    有时这个大数并不是特别大,可以用变长数据,反而会省空间,还快:

    struct BigInt {
        const static int mod = 10000;
        const static int DLEN = 4;
        vector<int> a;
        int len;
    
        BigInt() {
            a.resize(10);
            len = 1;
        }
    
        BigInt(int v) {
            a.resize(10);
            len = 0;
            do {
                a[len++] = v%mod;
                v /= mod;
            } while(v);
        }
    
        BigInt operator +(const BigInt &b)const {
            BigInt res;
            res.len = max(len,b.len);
            res.a.resize(res.len+1);
            for(int i = 0; i <= res.len; i++)
                res.a[i] = 0;
            for(int i = 0; i < res.len; i++) {
                res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0);
                res.a[i+1] += res.a[i]/mod;
                res.a[i] %= mod;
    
            }
            if(res.a[res.len] > 0)
                res.len++;
            return res;
        }
    
        BigInt operator *(const BigInt &b)const {
            BigInt res;
            res.a.resize(len + b.len);
            for(int i = 0; i < len; i++) {
                int up = 0;
                for(int j = 0; j < b.len; j++) {
                    int temp = a[i]*b.a[j] + res.a[i+j] + up;
                    res.a[i+j] = temp%mod;
                    up = temp/mod;
    
                }
                if(up != 0)
                    res.a[i + b.len] = up;
    
            }
            res.len = len + b.len;
            while(res.a[res.len - 1] == 0 &&res.len > 1)
                res.len--;
            return res;
        }
    
        bool operator >(const BigInt &b)const {
            if(len>b.len)
                return true;
            else if(len==b.len) {
                int ln=len-1;
                while(a[ln]==b.a[ln]&&ln>=0)
                    ln--;
                if(ln>=0&&a[ln]>b.a[ln])
                    return true;
                else
                    return false;
            } else
                return false;
        }
    
        void output() {
            printf("%d",a[len-1]);
            for(int i = len-2; i >=0 ; i--)
                printf("%04d",a[i]);
            printf("
    ");
        }
    };
    

    FFT高精度乘法

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int MAXN=1e4+10;
    inline int read() {
        char c=getchar();
        int x=0,f=1;
        while(c<'0'||c>'9') {
            if(c=='-')
                f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9') {
            x=x*10+c-'0';
            c=getchar();
        }
        return x*f;
    }
    
    const double Pi=acos(-1.0);
    struct Complex {
        double x,y;
        Complex(double xx=0,double yy=0) {
            x=xx,y=yy;
        }
        Complex operator+(const Complex& b)const {
            return Complex(x+b.x,y+b.y);
        }
        Complex operator-(const Complex& b)const {
            return Complex(x-b.x,y-b.y);
        }
        Complex operator*(const Complex& b)const {
            return Complex(x*b.x-y*b.y,x*b.y+y*b.x);
        }
    } a[MAXN],b[MAXN];
    
    int N,M;
    int l,r[MAXN];
    int limit;
    
    void FFT(Complex *A,int type) {
        for(int i=0; i<limit; i++)
            if(i<r[i])
                swap(A[i],A[r[i]]);//求出要迭代的序列
        for(int mid=1; mid<limit; mid<<=1) { //待合并区间的中点
            Complex Wn(cos(Pi/mid), type*sin(Pi/mid));    //单位根
            for(int R=mid<<1,j=0; j<limit; j+=R) { //R是区间的右端点,j表示前已经到哪个位置了
                Complex w(1,0);//幂
                for(int k=0; k<mid; k++,w=w*Wn) { //枚举左半部分
                    Complex x=A[j+k],y=w*A[j+mid+k];//蝴蝶效应
                    A[j+k]=x+y;
                    A[j+mid+k]=x-y;
                }
            }
        }
    }
    
    void Mult(int n,int m,vector<int> A,vector<int> B) {
        //两个多项式的度数
        for(int i=0; i<=n; i++)
            a[i].x=A[i],a[i].y=0;
        for(int i=0; i<=m; i++)
            b[i].x=B[i],b[i].y=0;
        for(limit=1; limit<=N+M;)
            limit<<=1,l++;
        for(int i=0; i<limit; i++)
            r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
        FFT(a,1);
        FFT(b,1);
        for(int i=0; i<=limit; i++)
            a[i]=a[i]*b[i];
        FFT(a,-1);
        for(int i=0; i<=N+M; i++) {
            a[i].x=(int)(a[i].x/limit+0.5);
        }
        return;
    }
    
    struct BigInt {
        const static int mod = 10000;
        const static int DLEN = 4;
        vector<int> a;
        int len;
    
        BigInt() {
            a.resize(4);
            len = 1;
        }
    
        BigInt(int v) {
            a.resize(4);
            len = 0;
            do {
                a[len++] = v%mod;
                v /= mod;
            } while(v);
        }
    
        BigInt operator *(const BigInt &b)const {
            BigInt res;
            res.a.resize(len+b.len);
            for(int i=0;i<len;i++) {
                int up=0;
                for(int j=0;j<b.len;j++) {
                    int temp=a[i]*b.a[j]+res.a[i+j]+up;
                    res.a[i+j]=temp%mod;
                    up=temp/mod;
                }
                if(up != 0)
                    res.a[i+b.len]=up;
            }
            res.len=len+b.len;
            while(res.a[res.len-1]==0&&res.len>1)
                res.len--;
            return res;
        }
    
        bool operator >(const BigInt &b)const {
            if(len>b.len)
                return true;
            else if(len==b.len) {
                int ln=len-1;
                while(a[ln]==b.a[ln]&&ln>=0)
                    ln--;
                if(ln>=0&&a[ln]>b.a[ln])
                    return true;
                else
                    return false;
            } else
                return false;
        }
    
        void output() {
            printf("%d",a[len-1]);
            for(int i = len-2; i >=0 ; i--)
                printf("%04d",a[i]);
            printf("
    ");
        }
    };
    
    BigInt BigInt_Mult_FFT(const BigInt &A,const BigInt &B) {
        Mult(A.len,B.len,A.a,B.a);
        BigInt res;
        res.len=A.len+B.len;
        for(int i=0; i<=res.len; i++)
            res.a[i]=a[i].x;
        while(res.len>1&&res.a[res.len-1]==0)
            res.len--;
        for(int i=0; i<res.len; i++) {
            res.a[i+1]+=res.a[i]/BigInt::mod;
            res.a[i]%=BigInt::mod;
        }
        if(res.a[res.len]>0)
            res.len++;
        return res;
    }
    
    int arr[205];
    BigInt dp[205][205];
    //区间[i,j]分为k段取得的最大值
    
    inline int sumarr(int i,int j) {
        return arr[j]-arr[i-1];
    }
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in","r",stdin);
    #endif // Yinku
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; i++) {
            scanf("%d",&arr[i]);
        }
        for(int i=1; i<=n; i++) {
            arr[i]+=arr[i-1];
        }
    
        for(int i=1; i<=n; i++) {
            dp[i][1]=BigInt(sumarr(1,i));
        }
    
        for(int i=2; i<=n; i++) {
            int c=min(i,k);
            for(int ki=2; ki<=c; ki++) {
                for(int p=1; p<=i-1; p++) {
                    BigInt t=dp[p][ki-1]*BigInt(sumarr(p+1,i));
                    //BigInt t=BigInt_Mult_FFT(dp[p][ki-1],BigInt(sumarr(p+1,i)));
                    if(t>dp[i][ki]) {
                        dp[i][ki]=t;
                    }
                }
            }
        }
    
        dp[n][k].output();
    }
    
  • 相关阅读:
    catalina配置参数
    zabbix搭建
    tomcat域名配置
    javaweb学习总结(十)——HttpServletRequest对象(一)
    javaweb学习总结(九)—— 通过Servlet生成验证码图片
    javaweb学习总结(八)——HttpServletResponse对象(二)
    javaweb学习总结(七)——HttpServletResponse对象(一)
    javaweb学习总结(六)——Servlet开发(二)
    javaweb学习总结(五)——Servlet开发(一)
    javaweb学习总结(四)——Http协议
  • 原文地址:https://www.cnblogs.com/Yinku/p/11008612.html
Copyright © 2011-2022 走看看