题解P1707 刷题比赛

P1707 刷题比赛

一道显而易见的矩阵加速题,只需要将转移矩阵按照题目的要求构建出来就行了。

状态矩阵

\[\begin{vmatrix} a_{k+1}&b_{k+1}&c_{k+1}&a_k&b_k&c_k&k^2&k&w^k&z&k&1 \end{vmatrix}\]

转移矩阵

\[\begin{vmatrix}p&1&1&1&0&0&0&0&0&0&0\\1&u&1&0&1&0&0&0&0&0&0\\1&1&x&0&0&1&0&0&0&0&0\\q&0&0&0&0&0&0&0&0&0&0\\0&v&0&0&0&0&0&0&0&0&0\\0&0&y&0&0&0&0&0&0&0&0\\r&0&0&0&0&0&1&0&0&0&0\\t&0&1&0&0&0&2&1&0&0&0\\0&1&0&0&0&0&0&0&w&0&0\\0&0&1&0&0&0&0&0&0&z&0\\1&0&2&0&0&0&1&1&0&0&1 \end{vmatrix}\]

然后直接套板子就可以了

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define lll __int128
using namespace std;
typedef long long ll;

ll n, m;
struct matrix 
{
    ll dt[12][12];
    matrix operator * (const matrix b) const
    {
        matrix c;
        memset(c.dt, 0, sizeof(c.dt));
        for (int i = 1; i <= 11; i++)
            for (int j = 1; j <= 11; j++)
                for (int k = 1; k <= 11; k++)
                    c.dt[i][j] = (c.dt[i][j] + (lll)dt[i][k] * b.dt[k][j]) % m;
        return c;
    }
} a, ito;

matrix qmi(matrix base, ll b)
{
    matrix res;
    memset(res.dt, 0, sizeof(res.dt));
    for (int i = 1; i <= 11; i++)
        res.dt[i][i] = 1;
    while (b)
    {
        if (b & 1)
            res = res * base;
        base = base * base;
        b >>= 1;
    }
    return res;
}

int main()
{
    scanf("%lld%lld", &n, &m);
    int p, q, r, t, u, v, w, x, y, z;
    scanf("%d%d%d%d%d%d%d%d%d%d", &p, &q, &r, &t, &u, &v, &w, &x, &y, &z);
    a.dt[1][1] = a.dt[1][2] = a.dt[1][3] = 3;
    a.dt[1][4] = a.dt[1][5] = a.dt[1][6] = a.dt[1][7] = a.dt[1][8] = 1;;
    a.dt[1][9] = w, a.dt[1][10] = z, a.dt[1][11] = 1;
    ito.dt[1][1] = p, ito.dt[1][2] = ito.dt[1][3] = ito.dt[1][4] = 1;
    ito.dt[2][1] = ito.dt[2][3] = ito.dt[2][5] = 1, ito.dt[2][2] = u;
    ito.dt[3][1] = ito.dt[3][2] = ito.dt[3][6] = 1, ito.dt[3][3] = x;
    ito.dt[4][1] = q, ito.dt[5][2] = v, ito.dt[6][3] = y;
    ito.dt[7][1] = r, ito.dt[7][7] = 1;
    ito.dt[8][1] = t, ito.dt[8][7] = 2, ito.dt[8][8] = ito.dt[8][3] = 1;
    ito.dt[9][2] = 1, ito.dt[9][9] = w;
    ito.dt[10][3] = 1, ito.dt[10][10] = z;
    ito.dt[11][1] = ito.dt[11][7] = ito.dt[11][8] = ito.dt[11][11] = 1, ito.dt[11][3] = 2;
    a = a * qmi(ito, n - 2);
    printf("nodgd %lld\nCiocio %lld\nNicole %lld", a.dt[1][1], a.dt[1][2], a.dt[1][3]);
    return 0;
}
posted @ 2021-03-07 20:01  DSHUAIB  阅读(62)  评论(0)    收藏  举报