Cattle off - Fibonacci number convolution

Topic Portal

sol:

Just simple deduction official solution to a problem I can not push it, push a long time actually launched another solution.

Is represented by c [i] [j] a [i] to item j, for example c [3] [0] = f [0] * f [3] = 0; c [4] [1] = f [1] * f [3] = 2;

We find a [n] is c [n] [0] + c [n] [1] + ... + c [n] [n];

c[n][0] = f[0] * f[n] = f[0] * f[n - 1] + f[0] * f[n - 2] = c[n - 1][0] + c[n - 2][0];

c[n][1] = f[1] * f[n - 1] = f[1] * f[n - 2] + f[1] * f[n - 3] = c[n - 1][1] + c[n - 2][1];

Seems to be found on the a [n] = a [n - 1] + a [n - 2]; but a [n], a [n - 1], a [n - 2] does not match the number of items;

c [n] [n] = f [n] * f [0] = f [n] * f [-1] + f [n] * f [-2], can not be used where c [n - 1] [n], and c [n - 2] [n] is represented, but the f [0] = 0, so the c [n] [n] = 0; can be ignored;

And because f [1] = 1, so c [n] [n - 1] = f [n - 1] * f [1] = f [n - 1];

c [n - 1] [n - 1] is also equal to 0;

Therefore, a [n] = a [n - 1] + a [n - 1] + f [n - 1] can then be solved using matrix exponentiation quickly that the subject.

  • Fast power matrix
    #include "bits/stdc++.h"
    using namespace std;
    typedef long long LL;
    const int MOD = 998244353;
    struct Mat {
        int mat[5][5];
        Mat() {memset(mat, 0, sizeof(mat));}
        friend Mat operator * (Mat a, Mat b) {
            Mat c;
            for (int k = 1; k <= 4; k++)
            for (int i = 1; i <= 4; i++)
            for (int j = 1; j <= 4; j++)
            c.mat[i][j] = (c.mat[i][j] + 1LL * a.mat[i][k] * b.mat[k][j]) % MOD;
            return c;
        }
    };
    Mat mat_pow(Mat n, LL k) {
        Mat ans;
        for (int i = 1; i <= 4; i++)
            ans.mat[i][i] = 1;
        while (k) {
            if (k & 1) ans = ans * n;
            n = n * n;
            k >>= 1;
        }
        return ans;
    }
    int main() {
        LL n;
        scanf("%lld", &n);
        Mat m;
        m.mat[1][1] = m.mat[1][2] = m.mat[1][3] = 1;
        m.mat[2][1] = m.mat[4][3] = 1;
        m.mat[3][3] = m.mat[3][4] = 1;
        m = mat_pow(m, n - 1);
        printf("%d\n", m.mat[1][3]);
        return 0;
    }

     

Guess you like

Origin www.cnblogs.com/Angel-Demon/p/11579966.html