1. 程式人生 > 實用技巧 >大數乘法,分治O(n^1.59)

大數乘法,分治O(n^1.59)

大數乘法實現,面試時候碰到,fft太難背了。。寫個分治應該可以滿足要求。具體時間複雜度證明這裡不貼了,大概是 O(n^1.59)。
程式碼:

class bignum{
    string val;
    public:
    bignum operator *(int b){
        bignum a = (*this);
        int n = a.val.size();
        bignum ret("");
        int c = 0,p = 0;
        for(int i = 0; i < n; i++){
            c = b * (a.val[i] - '0') + p;
            ret.val += c % 10 + '0';
            p = c / 10;
        }
        if(p != 0) ret.val += p + '0';
        return ret;
    }
    bignum operator +(bignum b){
        bignum a = (*this);
        if(a.val.size()<b.val.size()) swap(a,b);
        int n = a.val.size();
        bignum ret("");
        int c = 0,p = 0;
        for(int i = 0; i < n; i++){
            c = (a.val[i] - '0') + p;
            if(i < b.val.size()) c += (b.val[i] - '0');
            ret.val += c % 10 + '0';
            p = c / 10;
        }
        if(p != 0) ret.val += p + '0';
        return ret;
    }
    bignum(string s){
        reverse(s.begin(), s.end());
        val=s;
    }
    bignum operator *(bignum b){
        bignum a = (*this);
        int n = a.val.size();
        int m = b.val.size();
        if(n > m) swap(a, b),swap(n, m);
        if(n == 1){
            return b * (a.val[0] - '0');
        }
        else{
            int i,k = n / 2,l = m / 2;
            bignum A("");
            bignum B("");
            string tx,ty;
            for(i = 0; i < k; i++) A.val += a.val[i],ty += '0';
            for(; i < n; i++) B.val += a.val[i];
            bignum C("");
            bignum D("");
            for(i = 0; i < l; i++) C.val += b.val[i],tx += '0';
            for(; i < m; i++) D.val += b.val[i];
            bignum w = A * C;
            bignum x = A * D;
            x.val = tx + x.val;
            bignum y = B * C;
            y.val = ty + y.val;
            bignum z = B * D;
            z.val = tx + ty + z.val;
            return w + x + y + z;
        }
    }
    friend ostream & operator << (ostream &out, const bignum &c){
        string s = c.val;
        reverse(s.begin(), s.end());
        out << s;
        return out;
    }
};