[CF1182E] Product Oriented Recurrence - 矩阵快速幂

[CF1182E] Product Oriented Recurrence - 矩阵快速幂

Description

当 \(x \geq 4\) 时,\(f_x = c^{2x - 6} \cdot f_{x - 1} \cdot f_{x - 2} \cdot f_{x - 3}\) 。现在已知 \(n,f_1,f_2,f_3,c\) 的值,求 \(f_n\) 的值,对 \(10^9 + 7\) 取模。\((4 \leq n \leq 10^{18},1 \leq f_1,f_2,f_3,c \leq 10^9)\)

Solution

显然 \(f_n=c^?f_1^?f_2^?f_3^?\),指数显然是可以线性递推的,用矩阵快速幂优化即可

#include <bits/stdc++.h>
using namespace std;

#define int long long

int n, f1, f2, f3, c;
const int MOD = 1e9 + 7;
const int mod = 1e9 + 6;

struct Matrix
{
    int n, m;
    int a[7][7];

    Matrix()
    {
        memset(a, 0, sizeof a);
    }

    int *operator[](int id)
    {
        return a[id];
    }

    Matrix operator*(const Matrix &rhs)
    {
        assert(m == rhs.n);
        Matrix res;
        res.n = n;
        res.m = rhs.m;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= rhs.m; j++)
            {
                for (int k = 1; k <= m; k++)
                {
                    res[i][j] += a[i][k] * rhs.a[k][j];
                    res[i][j] %= mod;
                }
            }
        }
        return res;
    }
};

Matrix a0, a1, b0, b1, b2, b3;

Matrix qpow(Matrix p, int q)
{
    Matrix I;
    I.n = p.n;
    I.m = p.m;
    for (int i = 1; i <= I.n; i++)
        I[i][i] = 1;
    return (q & 1 ? p : I) * (q ? qpow(p * p, q / 2) : I);
}

const int eff[] = {1, 1, 1, 2, mod - 4, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 3, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0};

void load()
{
    int pos = 0;
    a0.n = a0.m = 5;
    for (int i = 1; i <= 5; i++)
        for (int j = 1; j <= 5; j++)
            a0[i][j] = eff[pos++];
    a1.n = a1.m = 3;
    for (int i = 1; i <= 3; i++)
        for (int j = 1; j <= 3; j++)
            a1[i][j] = eff[pos++];
    b0.n = 5;
    b0.m = 1;
    b1.n = 3;
    b1.m = 1;
    b2.n = 3;
    b2.m = 1;
    b3.n = 3;
    b3.m = 1;
    for (int i = 1; i <= 5; i++)
        b0[i][1] = eff[pos++];
    for (int i = 1; i <= 3; i++)
        b1[i][1] = eff[pos++];
    for (int i = 1; i <= 3; i++)
        b2[i][1] = eff[pos++];
    for (int i = 1; i <= 3; i++)
        b3[i][1] = eff[pos++];
}

int calc(int n, Matrix a, Matrix b)
{
    n -= 3;
    Matrix c = qpow(a, n);
    Matrix d = c * b;
    return d[1][1];
}

int qpow(int p, int q)
{
    return (q & 1 ? p : 1) * (q ? qpow(p * p % MOD, q / 2) : 1) % MOD;
}

int getf()
{
    int qc = calc(n, a0, b0);
    int q1 = calc(n, a1, b1);
    int q2 = calc(n, a1, b2);
    int q3 = calc(n, a1, b3);
    return qpow(c, qc) * qpow(f1, q1) % MOD * qpow(f2, q2) % MOD * qpow(f3, q3) % MOD;
}

signed main()
{
    ios::sync_with_stdio(false);
    load();
    cin >> n >> f1 >> f2 >> f3 >> c;
    cout << getf() << endl;
}
上一篇:2、构造/析构/赋值运算


下一篇:右值引用