标签: 多项式取模

  • BZOJ4162 shlw loves matrix II

    $$ \text{对于矩阵}M,\text{构造其特征多项式}G\left( x \right) \\ \text{则有}M^n=G\left( M \right) Q\left( M \right) +R\left( M \right) \\ \text{即}M^n\equiv R\left( M \right) \left( mod\,\,G\left( M \right) \right) \\ \text{即}x^n\equiv R\left( x \right) \left( \text{mod }G\left( x \right) \right) \\ \text{考虑特征多项式如何计算。} \\ G\left( x \right) =\det \left( M-x\text{I} \right) ,\text{其中}I\text{为单位矩阵} \\ \text{由于}G\left( x \right) \text{为}n\text{次多项式}\left( n\text{为矩阵大小} \right) ,\text{故可以通过插值求出来对应的特征多项式。} \\
    \\ \text{然后多项式快速幂}+\text{取模即可} $$

    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <string>
    using int_t = long long int;
    using std::cin;
    using std::cout;
    using std::endl;
    
    const int_t mod = 1000000007;
    const int_t LARGE = 103;
    struct Matrix {
        int_t data[LARGE + 1][LARGE + 1];
        int_t n;
        Matrix(int_t n) {
            this->n = n;
            memset(data, 0, sizeof(data));
        }
        int_t at(int_t r, int_t c) const { return data[r][c]; }
        int_t* operator[](int_t r) { return data[r]; }
        Matrix operator*(const Matrix& rhs) const {
            Matrix result(n);
            for (int_t i = 1; i <= n; i++)
                for (int_t j = 1; j <= n; j++)
                    for (int_t k = 1; k <= n; k++) {
                        result[i][j] =
                            (result[i][j] + data[i][k] * rhs.at(k, j) % mod) % mod;
                    }
            return result;
        }
        Matrix operator+(const Matrix& rhs) const {
            Matrix result(n);
            for (int_t i = 1; i <= n; i++)
                for (int_t j = 1; j <= n; j++) {
                    result[i][j] = (data[i][j] + rhs.at(i, j)) % mod;
                }
            return result;
        }
        Matrix operator-() const {
            Matrix result = *this;
            for (int_t i = 1; i <= n; i++)
                for (int_t j = 1; j <= n; j++)
                    result[i][j] = (mod - result[i][j] + mod) % mod;
            return result;
        }
        Matrix operator*(int_t k) const {
            Matrix result = *this;
            for (int_t i = 1; i <= n; i++)
                for (int_t j = 1; j <= n; j++)
                    result[i][j] = (result[i][j] * k) % mod;
            return result;
        }
        Matrix operator-(const Matrix& rhs) const { return (*this) + (-rhs); }
    };
    int_t power(int_t base, int_t index) {
        if (index < 0) {
            index = (index % (mod - 1) + mod - 1) % (mod - 1);
        }
        int_t result = 1;
        while (index) {
            if (index & 1) result = result * base % mod;
            base = base * base % mod;
            index >>= 1;
        }
        return result;
    }
    
    void poly_mul(const int_t* A, int_t n, const int_t* B, int_t m, int_t* C) {
        static int_t Cx[LARGE + 1];
        std::fill(Cx, Cx + n + m + 1, 0);
        for (int_t i = 0; i <= n; i++)
            for (int_t j = 0; j <= m; j++)
                Cx[i + j] = (Cx[i + j] + A[i] * B[j] % mod) % mod;
        std::copy(Cx, Cx + n + m + 1, C);
    }
    void poly_div(const int_t* A, int_t n, const int_t* B, int_t m, int_t* R,
                  int_t* Q) {
        while (B[m] % mod == 0) m--;
        if (n < m) {
            std::fill(Q, Q + n - m + 1, 0);
            std::copy(A, A + n + 1, R);
            return;
        }
        std::copy(A, A + n + 1, R);
        for (int_t i = n - m; i >= 0; i--) {
            Q[i] = R[i + m] * power(B[m], -1) % mod;
            for (int_t j = m; j >= 0; j--) {
                R[i + j] = (R[i + j] - Q[i] * B[j] % mod + mod) % mod;
            }
        }
    }
    void interpolate(int_t* X, int_t* Y, int_t n, int_t* result) {
        static int_t prod[LARGE + 1];
        prod[0] = 1;
        for (int_t i = 1; i <= n; i++) {
            int_t Z[] = {mod - X[i], 1};
            poly_mul(prod, i - 1, Z, 1, prod);
        }
    #ifdef DEBUG
        for (int_t i = 0; i <= n; i++) cout << prod[i] << " ";
        cout << endl;
    
    #endif
        for (int_t i = 1; i <= n; i++) {
            int_t coef = 1;
            for (int_t j = 1; j <= n; j++)
                if (i != j) {
                    coef = coef * (X[i] - X[j] + mod) % mod;
                }
            coef = Y[i] * power(coef, -1) % mod;
            static int_t curr[LARGE + 1], R[LARGE + 1];
            int_t B[] = {mod - X[i], 1};
            poly_div(prod, n, B, 1, R, curr);
    #ifdef DEBUG
            cout << "div x-" << X[i] << " = ";
            for (int_t i = 0; i <= n - 1; i++) cout << curr[i] << " ";
            cout << endl;
            cout << "coef = " << coef << endl;
            cout << endl;
    #endif
            for (int_t i = 0; i < n; i++)
                result[i] = (result[i] + coef * curr[i] % mod) % mod;
        }
    }
    int_t det(Matrix mat) {
        int_t prod = 1;
        for (int_t i = 1; i <= mat.n; i++) {
            int_t next = -1;
            for (int_t j = i; j <= mat.n; j++)
                if (mat[i][j]) {
                    next = j;
                    break;
                }
            if (next == -1) return 0;
            if (next != i) {
                prod *= -1;
                std::swap(mat.data[i], mat.data[next]);
            }
            for (int_t j = i + 1; j <= mat.n; j++) {
                int_t f = mat[j][i] * power(mat[i][i], -1) % mod;
                for (int_t k = i; k <= mat.n; k++) {
                    mat[j][k] = (mat[j][k] - f * mat[i][k] % mod + mod) % mod;
                }
            }
        }
        prod = mod + prod;
        for (int_t i = 1; i <= mat.n; i++) prod = prod * mat[i][i] % mod;
        return prod;
    }
    void poly_power(const int_t* A, int_t n, const int_t* B, int_t m,
                    const std::string& str, int_t* result) {
        static int_t base[LARGE + 1], Q[LARGE + 1];
        result[0] = 1;
        std::copy(A, A + n + 1, base);
        for (int_t i = 0; i < str.length(); i++) {
            if (str[i] == '1') {
                poly_mul(result, m - 1, base, m - 1, result);
                poly_div(result, 2 * m - 1, B, m, result, Q);
            }
            poly_mul(base, m - 1, base, m - 1, base);
            poly_div(base, 2 * m - 1, B, m, base, Q);
        }
    }
    int main() {
        std::string index;
        cin >> index;
        std::reverse(index.begin(), index.end());
    
        int_t n;
        cin >> n;
        Matrix mat(n), I(n);
        static int_t X[LARGE + 1], Y[LARGE + 1], result[LARGE + 1];
        for (int_t i = 1; i <= n; i++) {
            for (int_t j = 1; j <= n; j++) cin >> mat[i][j];
            I[i][i] = 1;
        }
    
        for (int_t i = 1; i <= 1 + n; i++) {
            X[i] = i;
    #ifdef DEBUG
            // auto curr=mat - I * i;
            // cout<<"sub "
    #endif
            Y[i] = det(mat - I * i);
    #ifdef DEBUG
    
            cout << "(" << X[i] << "," << Y[i] << ")" << endl;
    #endif
        }
        interpolate(X, Y, n + 1, result);
        // for (int_t i = 0; i <= n; i++) cout << result[i] << " ";
        // cout << endl;
        static int_t A[LARGE + 1];
        static int_t result_poly[LARGE + 1];
        A[1] = 1;
        poly_power(A, 1, result, n, index, result_poly);
    #ifdef DEBUG
        for (int_t i = 0; i < n; i++) cout << result_poly[i] << " ";
        cout << endl;
    #endif
        Matrix result_mat(n), curr = I;
        for (int_t i = 0; i < n; i++) {
            result_mat = result_mat + curr * result_poly[i];
            curr = curr * mat;
        }
        for (int_t i = 1; i <= n; i++) {
            for (int_t j = 1; j <= n; j++) {
                cout << result_mat[i][j] << " ";
            }
            cout << endl;
        }
        return 0;
    }

     

  • 常系数线性递推

    https://www.luogu.org/problemnew/show/P4723

    NOIP之后学的第一个新东西…

    不带常数项的线性递推。

    (其实带常数项也能做,不过复杂一点)

    复杂度$O(nlognlogk)$,常数上天。

    前置知识:多项式取模,多项式快速幂。

    $$ \text{设数列}a_n=\sum_{1\le i\le k}{a_{n-i}\times f_i} \\ \ \text{设向量} \\ X=\left[ \begin{matrix} a_0& a_1& ….& a_{k-1}\\ \end{matrix} \right] \\ \text{设转移矩阵} \\ A=\left[ \begin{matrix}{l} 0& 0& 0& …& f_{n-k}\\ 1& 0& 0& …& f_{n-k+1}\\ …& …& …& …& …\\ 0& 0& 1& …& f_2\\ 0& 0& 0& …& f_1\\ \end{matrix} \right] \\ \text{则结果为}\left( XA^n \right) _0 \\ \text{构造向量}c=\left[ \begin{matrix} c_0& c_1& …& c_{k-1}\\ \end{matrix} \right] ,\text{满足}A^n=\sum_{0\le i\le k-1}{A^ic_i} \\ \text{则}X\times A^n=\sum_{0\le i\le k-1}{c_iX\times A^i} \\ \text{所以}\left( X\times A^n \right) _0=\sum_{0\le i\le k-1}{c_i\left( X\times A^i \right) _0} \\ \text{单独拿出来向量的第0项,这个式子仍然成立,因为向量中的一列与其他列的值互不相关} \\ \text{因为}0\le i\le k-\text{1,所以}\left( X\times A^i \right) _0\text{相当于}X_i \\ \left( X\times A^n \right) _0=\sum_{0\le i\le k-1}{c_iX_i} \\ \text{现在考虑如何构造序列}c \\ \text{设}k-\text{1次多项式}R\left( x \right) =\sum_{0\le i\le k-1}{c_ix^i} \\ \text{考虑矩阵}A\text{的零化多项式}G\left( A \right) ,\text{满足}G\left( A \right) =0 \\ \text{那么}A^n=\sum_{0\le i\le k-1}{c_iA^i}=R\left( A \right) =Q\left( A \right) G\left( A \right) +R\left( A \right) \\ \text{即} \\ x^n=Q\left( x \right) G\left( x \right) +R\left( x \right) \\ \text{假设}G\left( x \right) ,\text{即矩阵}A\text{的零化多项式,是个}k\text{次多项式,那么} \\ x^n\equiv R\left( x \right) \left( mod\ G\left( k \right) \right) \\ \text{所以知道了}G\left( x \right) \text{之后,通过多项式快速幂}+\text{多项式取模,即可计算出序列}c\text{,进而计算线性递推的值} \\ \text{现在的问题在于如何求出矩阵}A\text{的零化多项式}G\left( A \right) \\ \\ \text{矩阵的特征向量和特征值:} \\ \text{对于矩阵}A\text{,如果存在行向量}v\text{和数}x,\text{满足} \\ vA=vx \\ \text{则称}v\text{为矩阵}A\text{的一个特征向量,}x\text{为矩阵}A\text{的一个特征值} \\ vA-vx=0 \\ v\left( A-Ix \right) =0 \\ \text{设}B=A-Ix\text{为}A\text{的特征矩阵} \\ \text{则该矩阵的行列式}G\left( x \right) =\det \left( B \right) \text{称为}A\text{的特征多项式,}G\left( x \right) \text{满足}G\left( A \right) =0 \\ \text{现在的问题在于求出常系数线性递推矩阵的行列式的值} \\ \text{假设有常系数线性递推系数向量}\left[ \begin{matrix} a_1& a_2& …& a_n\\ \end{matrix} \right] \\ \text{则对应的递推矩阵} \\ A=\left[ \begin{matrix}{l} 0& 0& …& 0& a_n\\ 1& 0& …& 0& a_{n-1}\\ …& ..& …& …& …\\ 0& 0& …& 0& a_2\\ 0& 0& …& 1& a_1\\ \end{matrix} \right] \\ \text{则}A\text{的特征矩阵为} \\ B=\left[ \begin{matrix}{l} -x& 0& …& 0& a_n\\ 1& -x& …& 0& a_{n-1}\\ …& ..& …& …& …\\ 0& 0& …& -x& a_2\\ 0& 0& …& 1& a_1-x\\ \end{matrix} \right] \\ \text{根据行列式的相关性质,如果一个矩阵}A\text{的一行或者一列可以拆成两个行向量}x\text{或者两个列向量}y\text{的和,} \\ \text{那么这个矩阵的行列式等于} \\ \text{把这一行或者这一列换成对应的行向量或者列向量后,两个矩阵的行列式的和} \\ \text{例如} \\ \det \left( \left[ \begin{matrix} 1& 4\\ 2& 3\\ \end{matrix} \right] \right) =\det \left( \left[ \begin{matrix} 1& 4\\ 1& 1\\ \end{matrix} \right] \right) +\det \left( \left[ \begin{matrix} 1& 4\\ 1& 2\\ \end{matrix} \right] \right) =-3-2=-5 \\ \text{其中}\left[ \begin{matrix} 2& 3\\ \end{matrix} \right] =\left[ \begin{matrix} 1& 1\\ \end{matrix} \right] +\left[ \begin{matrix} 1& 2\\ \end{matrix} \right] \\ \text{所以把矩阵}B\text{最后一列拆掉} \\ \det \left( B \right) =\det \left( \left[ \begin{matrix}{l} -x& 0& …& 0& 0\\ 1& -x& …& 0& 0\\ 0& 1& …& 0& 0\\ 0& 0& …& -x& 0\\ 0& 0& …& 1& -x\\ \end{matrix} \right] \right) +\det \left( \left[ \begin{matrix}{l} -x& 0& …& 0& a_n\\ 1& -x& …& 0& a_{n-1}\\ …& …& …& …& …\\ 0& 0& …& -x& a_2\\ 0& 0& …& 1& a_1\\ \end{matrix} \right] \right) \\ =\left( -x \right) ^n+\det \left( \left[ \begin{matrix}{l} -x& 0& …& 0& a_n\\ 1& -x& …& 0& a_{n-1}\\ …& …& …& …& …\\ 0& 0& …& -x& a_2\\ 0& 0& …& 1& a_1\\ \end{matrix} \right] \right) \\ \text{继续根据行列式的相关性质,矩阵的行列式可以按照一行或者一列展开} \\ \text{所以把矩阵}\left[ \begin{matrix}{l} -x& 0& …& 0& a_n\\ 1& -x& …& 0& a_{n-1}\\ …& …& …& …& …\\ 0& 0& …& -x& a_2\\ 0& 0& …& 1& a_1\\ \end{matrix} \right] \text{按照最后一列展开,} \\ \text{则其代数余子式}M_{in}=a_i\times \left( -1 \right) ^{2n+1-i}\times \left( -x \right) ^{n-i} \\ \text{则}\det \left( \left[ \begin{matrix}{l} -x& 0& …& 0& a_n\\ 1& -x& …& 0& a_{n-1}\\ …& …& …& …& …\\ 0& 0& …& -x& a_2\\ 0& 0& …& 1& a_1\\ \end{matrix} \right] \right) =\sum_{1\le i\le n}{a_i\times \left( -1 \right) ^{2n+1-i}\times \left( -x \right) ^{n-i}} \\ =\sum_{1\le i\le n}{a_i\times \left( -1 \right) ^{2n}\times \left( -1 \right) ^{1-i}\times \left( -1 \right) ^n\times \left( -1 \right) ^{-i}\times x^{n-i}} \\ =-\left( -1 \right) ^n\sum_{1\le i\le n}{a_i\times x^{n-i}}=-\left( -1 \right) ^n\sum_{0\le i\le n-1}{a_{n-i}x^i} \\ \text{则}\det \left( B \right) =\left( -x \right) ^n-\left( -1 \right) ^n\times \sum_{0\le i\le n-1}{a_{n-i}x^i} \\ =\left( -1 \right) ^n\left( x^n-\sum_{0\le i\le n-1}{a_{n-i}x^i} \right) \\ \text{所以我们可以}O\left( n \right) \text{时间内构造出线性递推矩阵的特征多项式。} \\ \text{接下来只需要多项式快速幂}+\text{取模即可构造出序列}c $$

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <assert.h>
    #define debug(x) std::cout << #x << " = " << x << std::endl;
    
    using int_t = long long int;
    
    using std::cin;
    using std::cout;
    using std::endl;
    
    const int_t mod = 998244353;
    const int_t g = 3;
    const int_t LARGE = 1 << 22;
    int_t power(int_t, int_t);
    int_t upper2n(int_t x);
    int_t bitRev(int_t x, int_t size2);
    void poly_inv(int_t *A, int_t *inv, int_t n);
    template <int_t arg = 1>
    void transform(int_t *A, int_t size);
    void poly_div(const int_t *A, int_t n, const int_t *B, int_t m, int_t *Q, int_t *R);
    void poly_power(const int_t *A, int_t n, int_t index, const int_t *B, int_t m, int_t *result);
    void poly_mul_mod(const int_t *A, int_t n, const int_t *B, int_t m, const int_t *M, int_t x, int_t *result, int_t *Qx = nullptr);
    
    int main()
    {
        int_t n, k;
        cin >> n >> k;
        static int_t f0[LARGE], coef[LARGE], A[LARGE], C[LARGE], B[LARGE];
        for (int_t i = 1; i <= k; i++)
            cin >> coef[i];
        for (int_t i = 0; i < k; i++)
            cin >> f0[i];
        //构造线性递推矩阵的特征多项式
        A[k] = 1;
        for (int_t i = 0; i < k; i++)
        {
            A[i] = -coef[k - i] + 2 * mod;
            A[i] %= mod;
        }
        B[1] = 1;
        //多项式快速幂
        poly_power(B, 1, n, A, k, C);
        int_t result = 0;
        for (int_t i = 0; i < k; i++)
            result = (result + C[i] * f0[i] % mod + 2 * mod) % mod;
        cout << result << endl;
        return 0;
    }
    //计算n次多项式A整除m次多项式B的商和余数
    void poly_div(const int_t *A, int_t n, const int_t *B, int_t m, int_t *Q, int_t *R)
    {
        static int_t Ax[LARGE], Bx[LARGE], Qx[LARGE], Binv[LARGE];
        //注意不要开小,至少2n
        int_t size = upper2n(n * 2 + 1);
        for (int_t i = 0; i < size; i++)
        {
            Ax[i] = Bx[i] = Qx[i] = Binv[i] = 0;
        }
        for (int_t i = 0; i <= n; i++)
        {
            Ax[i] = A[n - i];
        }
        for (int_t i = 0; i <= m; i++)
        {
            Bx[i] = B[m - i];
        }
    
        for (int_t i = n - m + 1; i < size; i++)
        {
            Ax[i] = Bx[i] = Qx[i] = 0;
        }
        poly_inv(Bx, Binv, n - m + 1);
        for (int_t i = n - m + 1; i < size; i++)
        {
            Binv[i] = 0;
        }
        transform(Ax, size);
        transform(Binv, size);
        for (int_t i = 0; i < size; i++)
        {
            Qx[i] = Ax[i] * Binv[i] % mod;
        }
        transform<-1>(Qx, size);
        for (int_t i = 0; i <= n - m; i++)
        {
            Q[n - m - i] = Qx[i] * power(size, -1) % mod;
        }
        for (int_t i = 0; i < size; i++)
        {
            if (i <= n - m)
                Qx[i] = Q[i];
            else
                Qx[i] = 0;
        }
        for (int_t i = 0; i <= m; i++)
        {
            Bx[i] = B[i];
        }
    
        transform(Qx, size);
        transform(Bx, size);
        for (int_t i = 0; i < size; i++)
        {
            Qx[i] = Qx[i] * Bx[i] % mod;
        }
        transform<-1>(Qx, size);
        for (int_t i = 0; i <= m - 1; i++)
        {
            R[i] = (A[i] - Qx[i] * power(size, -1) % mod + 2 * mod) % mod;
        }
    }
    
    //求多项式A在模x^n下的逆元
    void poly_inv(int_t *A, int_t *inv, int_t n)
    {
        assert(n != 0);
        if (n == 1)
        {
            inv[0] = power(A[0], -1);
            return;
        }
        poly_inv(A, inv, n / 2 + n % 2);
        /*
        C(x)<-2B(x)-A(x)B(x)^2
        */
        int_t size = upper2n(n * 3 + 1);
        static int_t temp[LARGE];
        for (int_t i = 0; i < size; i++)
        {
            if (i < n)
                temp[i] = A[i];
            else
                temp[i] = 0;
        }
        transform(temp, size);
        transform(inv, size);
        for (int_t i = 0; i < size; i++)
        {
            inv[i] = (2 * inv[i] - temp[i] * inv[i] % mod * inv[i] % mod + 2 * mod) % mod;
        }
        transform<-1>(inv, size);
        for (int_t i = 0; i < size; i++)
        {
            if (i < n)
                inv[i] = inv[i] * power(size, -1) % mod;
            else
                inv[i] = 0;
        }
    }
    
    template <int_t arg = 1>
    void transform(int_t *A, int_t size)
    {
        int_t size2 = log2(size);
        for (int_t i = 0; i < size; i++)
        {
            int_t x = bitRev(i, size2);
            if (x > i)
            {
                std::swap(A[i], A[x]);
            }
        }
        for (int_t i = 2; i <= size; i *= 2)
        {
            int_t mr = power(g, arg * (mod - 1) / i);
            for (int_t j = 0; j < size; j += i)
            {
                int_t curr = 1;
                for (int_t k = 0; k < i / 2; k++)
                {
                    int_t u = A[j + k];
                    //把curr写成了mr
                    int_t t = A[j + k + i / 2] * curr % mod;
                    A[j + k] = (u + t) % mod;
                    A[j + k + i / 2] = (u - t + 2 * mod) % mod;
                    curr = curr * mr % mod;
                }
            }
        }
    }
    
    int_t upper2n(int_t x)
    {
        int_t res = 1;
        while (res < x)
            res *= 2;
        return res;
    }
    
    int_t bitRev(int_t x, int_t size2)
    {
        int_t res = 0;
        for (int_t i = 1; i < size2; i++)
        {
            res |= (x & 1);
            res <<= 1;
            x >>= 1;
        }
        return res | (x & 1);
    }
    
    int_t power(int_t base, int_t index)
    {
        const int_t phi = mod - 1;
        index = (index % phi + phi) % phi;
        base = (base % mod + mod) % mod;
        int_t result = 1;
        while (index)
        {
            if (index & 1)
                result = result * base % mod;
            base = base * base % mod;
            index >>= 1;
        }
        return result;
    }
    //计算A(x)B(x) mod M(x)
    void poly_mul_mod(const int_t *A, int_t n, const int_t *B, int_t m, const int_t *M, int_t x, int_t *result, int_t *Q)
    {
        static int_t Ax[LARGE], Bx[LARGE], Qx[LARGE];
    
        if (Q == nullptr)
            Q = Qx;
        int_t size = upper2n(n + m + 1);
        for (int_t i = 0; i < size; i++)
        {
            Ax[i] = Bx[i] = Q[i] = Qx[i] = 0;
        }
        for (int_t i = 0; i <= n; i++)
            Ax[i] = A[i];
        for (int_t i = 0; i <= m; i++)
            Bx[i] = B[i];
        transform(Ax, size);
        transform(Bx, size);
        for (int_t i = 0; i < size; i++)
            Ax[i] = Ax[i] * Bx[i] % mod;
        transform<-1>(Ax, size);
        for (int_t i = 0; i < size; i++)
        {
            if (i <= n + m)
                Ax[i] = Ax[i] * power(size, -1) % mod;
            else
                Ax[i] = 0;
        }
    
        poly_div(Ax, n + m + 1, M, x, Q, result);
    }
    //计算A(x)^index mod B(x)
    void poly_power(const int_t *A, int_t n, int_t index, const int_t *B, int_t m, int_t *result)
    {
        static int_t Ax[LARGE], Bx[LARGE], temp[LARGE], Q[LARGE];
        //结果多项式的次数
        int_t res_p = 0;
        result[0] = 1;
        int_t size = upper2n(m * 2 + 1);
        std::copy(A, A + n + 1, Ax);
        std::copy(B, B + m + 1, Bx);
        for (int_t i = 0; i <= m; i++)
            Bx[i] = (Bx[i] % mod + mod) % mod;
        while (index)
        {
            //每次乘之前要分次数大于等于模数还是小于模数考虑
            if (n >= m)
            {
                //次数大于等于模数的情况下,需要乘完以后取模
                if ((index & 1))
                {
                    poly_mul_mod(result, res_p, Ax, n, Bx, m, temp);
                    std::copy(temp, temp + m, result);
                    //每次乘完之后需要把次数更改好
                    //对一个m次多项式取模,余数的次数为m-1
                    res_p = m - 1;
                }
                poly_mul_mod(Ax, n, Ax, n, B, m, temp);
                std::copy(temp, temp + m, Ax);
                //还需要更改A的次数
                n = m - 1;
            }
            else
            {
                //次数没有超过模数,那么直接乘
                transform(Ax, size);
                if (index & 1)
                {
                    transform(result, size);
                    for (int_t i = 0; i < size; i++)
                    {
                        result[i] *= Ax[i];
                        result[i] %= mod;
                    }
                    transform<-1>(result, size);
                    for (int_t i = 0; i < size; i++)
                    {
                        result[i] = result[i] * power(size, -1) % mod;
                    }
                    res_p = res_p + n;
                }
                for (int_t i = 0; i < size; i++)
                {
                    Ax[i] *= Ax[i];
                    Ax[i] %= mod;
                }
                transform<-1>(Ax, size);
                for (int_t i = 0; i < size; i++)
                {
                    Ax[i] = Ax[i] * power(size, -1) % mod;
                }
                n *= 2;
            }
            //清空数组
            for (int_t i = res_p + 1; i < size; i++)
                result[i] = 0;
            for (int_t i = n + 1; i < size; i++)
                Ax[i] = 0;
            index >>= 1;
        }
        if (res_p >= m)
        {
            poly_div(result, res_p, B, m, Q, temp);
            std::copy(temp, temp + m, result);
        }
    }