dalao能帮我看看这个高精度模运算的问题
  • 板块学术版
  • 楼主shortintlonglong
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/10/22 10:54
  • 上次更新2023/10/22 11:43:19
查看原帖
dalao能帮我看看这个高精度模运算的问题
1045201
shortintlonglong楼主2023/10/22 10:54

如果有其它问题也请指出

#include <iostream>
#include <vector>
#include <algorithm>
#include <complex>

using namespace std;

typedef complex <double> Complex;
typedef vector <int> BigInt;

const double PI = acos(-1);

void FFT(vector <Complex> & poly, bool inverse) {
    int n = poly.size();
    if (n == 1) return;

    vector <Complex> even(n / 2), odd(n / 2);
    for (int i = 0, j = 0; i < n; i += 2, ++ j) {
        even[j] = poly[i];
        odd[j] = poly[i + 1];
    }

    FFT(even, inverse);
    FFT(odd, inverse);

    double angle = 2 * PI / n * (inverse ? -1 : 1);
    Complex w(1), wn(cos(angle), sin(angle));
    for (int i = 0; i < n / 2; ++ i) {
        Complex temp = w * odd[i];
        poly[i] = even[i] + temp;
        poly[i + n / 2] = even[i] - temp;
        w *= wn;
    }

    if (inverse) {
        for (int i = 0; i < n; ++ i) {
            poly[i] /= 2;
        }
    }
}

BigInt multiply(const BigInt& a, const BigInt& b) {
    vector <Complex> fa(a.begin(), a.end()), fb(b.begin(), b.end());
    int n = 1;
    while (n < max(a.size(), b.size())) {
        n <<= 1;
    }
    n <<= 1;
    fa.resize(n);
    fb.resize(n);

    FFT(fa, false);
    FFT(fb, false);
    for (int i = 0; i < n; ++ i) {
        fa[i] *= fb[i];
    }
    FFT(fa, true);

    BigInt result(n);
    for (int i = 0; i < n; ++ i) {
        result[i] = static_cast <int> (fa[i].real() + 0.5);
    }
    int carry = 0;
    for (int i = 0; i < n; ++ i) {
        result[i] += carry;
        carry = result[i] / 10;
        result[i] %= 10;
    }
    while (result.size() > 1 && result.back() == 0) {
        result.pop_back();
    }
    return result;
}

ostream& operator << (ostream& os, const BigInt& num) {
    for (int i = num.size() - 1; i >= 0; -- i) {
        os << num[i];
    }
    return os;
}

istream& operator >> (istream& is, BigInt& num) {
    string str;
    is >> str;
    num.resize(str.length());
    for (int i = 0; i < str.length(); ++ i) {
        num[i] = str[str.length() - i - 1] - '0';
    }
    return is;
}

bool operator < (const BigInt& a, const BigInt& b) {
    if (a.size() != b.size()) {
        return a.size() < b.size();
    }
    for (int i = a.size() - 1; i >= 0; -- i) {
        if (a[i] != b[i]) {
            return a[i] < b[i];
        }
    }
    return false;
}

bool operator > (const BigInt& a, const BigInt& b) {
    return b < a;
}

bool operator <= (const BigInt& a, const BigInt& b) {
    return !(a > b);
}

bool operator >= (const BigInt& a, const BigInt& b) {
    return !(a < b);
}

bool operator != (const BigInt& a, const BigInt& b) {
    return !(a == b);
}

bool operator == (const BigInt& a, const BigInt& b) {
    if (a.size() != b.size()) {
        return false;
    }
    for (int i = 0; i < a.size(); ++ i) {
        if (a[i] != b[i]) {
            return false;
        }
    }
    return true;
}

BigInt operator + (const BigInt& a, const BigInt& b) {
    BigInt result(max(a.size(), b.size()) + 1);
    int carry = 0;
    for (int i = 0; i < result.size(); ++ i) {
        int val = (i < a.size() ? a[i] : 0) + (i < b.size() ? b[i] : 0) + carry;
        result[i] = val % 10;
        carry = val / 10;
    }
    while (result.size() > 1 && result.back() == 0) {
        result.pop_back();
    }
    return result;
}

BigInt operator - (const BigInt& a, const BigInt& b) {
    BigInt result = a;
    int carry = 0;
    for (int i = 0; i < b.size() || carry; ++ i) {
        result[i] -= (i < b.size() ? b[i] : 0) + carry;
        carry = result[i] < 0;
        if (carry) {
            result[i] += 10;
        }
    }
    while (result.size() > 1 && result.back() == 0) {
        result.pop_back();
    }
    return result;
}

BigInt operator * (const BigInt& a, const BigInt& b) {
    return multiply(a, b);
}

BigInt operator / (const BigInt& a, const BigInt& b) {
    BigInt result, dividend = a;
    for (int i = a.size() - 1; i >= 0; -- i) {
        result = result * BigInt(1, 0) + BigInt(1, dividend[i]);
        while (result.size() > 1 && result.back() == 0) {
            result.pop_back();
        }
        int quotient = 0;
        int left = 0, right = 10;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (b * BigInt(1, mid) <= result) {
                quotient = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        result = result - b * BigInt(1, quotient);
        dividend[i] = quotient;
    }
    reverse(dividend.begin(), dividend.end());
    while (dividend.size() > 1 && dividend.back() == 0) {
        dividend.pop_back();
    }
    return dividend;
}

BigInt operator % (const BigInt& a, const BigInt& b) {
    BigInt result = a;
    for (int i = a.size() - 1; i >= 0; -- i) {
        result = result * BigInt(1, 10) + BigInt(1, a[i]);
        while (result.size() > 1 && result.back() == 0) {
            result.pop_back();
        }
        int quotient = 0;
        int left = 0, right = 10;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (b * BigInt(1, mid) <= result) {
                quotient = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        result = result - b * BigInt(1, quotient);
    }
    while (result.size() > 1 && result.back() == 0) {
        result.pop_back();
    }
    return result;
}

BigInt& operator += (BigInt& a, const BigInt& b) {
    return a = a + b;
}

BigInt& operator -= (BigInt& a, const BigInt& b) {
    return a = a - b;
}

BigInt& operator *= (BigInt& a, const BigInt& b) {
    return a = a * b;
}

BigInt& operator /= (BigInt& a, const BigInt& b) {
    return a = a / b;
}

BigInt& operator %= (BigInt& a, const BigInt& b) {
    return a = a % b;
}

BigInt& operator ++ (BigInt& num) {
    return num += BigInt(1, 1);
}

BigInt operator ++ (BigInt& num, int) {
    BigInt temp = num;
    ++ num;
    return temp;
}

BigInt& operator -- (BigInt& num) {
    return num -= BigInt(1, 1);
}

BigInt operator -- (BigInt& num, int) {
    BigInt temp = num;
    -- num;
    return temp;
}

bool operator ! (const BigInt& num) {
    return num == BigInt(1, 0);
}
2023/10/22 10:54
加载中...