>Link
luogu T202676
>Description
n ≤ 1 0 18 n\le10^{18} n≤1018
>解题思路
感觉就是自己脑子有坑QwQ 考场想到了矩阵快速幂然后伞兵了又觉得加速不了(…)然后就交了个DP上去QwQ 我就是菜
搞一个DP,设 f S , i , j f_{S,i,j} fS,i,j 为起点为 S S S,第 i i i秒到 j j j的方案数
然后预处理+矩阵快速幂加速,爆搜出每个点最终到的地方,累计答案就行了
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
#define N 100010
using namespace std;
const int xx[4] = {
-1, 0, 0, 1}, yy[4] = {
0, -1, 1, 0};
const LL Mod = 1e9 + 7;
struct matrix
{
int x, y;
LL a[15][15];
} A, B, ans;
int p[15][15], w[15];
LL n, sum, ANS, f[15][15];
bool use[15];
int getnum (int x, int y) {
return (x - 1) * 3 + y;}
matrix operator * (matrix a, matrix b)
{
matrix c;
c.x = a.x, c.y = b.y;
for (int i = 1; i <= c.x; i++)
for (int j = 1; j <= c.y; j++) c.a[i][j] = 0;
for (int i = 1; i <= c.x; i++)
for (int j = 1; j <= c.y; j++)
for (int k = 1; k <= a.y; k++)
c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j] % Mod) % Mod;
return c;
}
void power (LL k)
{
if (k == 1) {
B = A; return;}
power (k >> 1);
B = B * B;
if (k & 1) B = B * A;
}
LL solve (int S, int T)
{
ans.x = 1, ans.y = 9;
for (int i = 1; i <= 9; i++) ans.a[1][i] = 0;
ans.a[1][S] = 1;
ans = ans * B;
return ans.a[1][T];
}
void dfs (int now)
{
if (now > 9)
{
sum = 1;
for (int i = 1; i <= 9; i++)
sum = sum * f[i][w[i]] % Mod;
ANS = (ANS + sum) % Mod;
return;
}
for (int i = 1; i <= 9; i++)
if (!use[i])
{
use[i] = 1;
w[now] = i;
dfs (now + 1);
w[now] = 0;
use[i] = 0;
}
}
int main()
{
scanf ("%lld", &n);
int tx, ty, num;
for (int x = 1; x <= 3; x++)
for (int y = 1; y <= 3; y++)
{
num = getnum (x, y);
for (int i = 0; i < 4; i++)
{
tx = x + xx[i], ty = y + yy[i];
if (tx < 1 || tx > 3 || ty < 1 || ty > 3) continue;
p[num][getnum (tx, ty)] = 1;
}
p[num][num] = 1;
}
A.x = A.y = 9;
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++)
A.a[j][i] = p[i][j];
power (n);
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++)
f[i][j] = solve (i, j);
dfs (1);
printf ("%lld", ANS);
return 0;
}