Sample Input
2
3 1 2
4 1 10
Sample Output
85
369
Hint
In the first case, the third number is 85 = 21十2十3^4.
In the second case, the third number is 93 = 21十1*10十3^4 and the fourth number is 369 = 2 * 10 十 93 十 4^4.
思路: 矩阵乘法,构建矩阵有点难度,推出公式
F(n) = 2 * F(n - 2) + F(n - 1) + (n + 1)^4
然后单纯F(n + 1), F(n), F(n - 1)不能构建矩阵,需要将里面的所有变量都列出
F(n)
F(n - 1)
(n + 1) ^ 4
(n + 1) ^ 3
(n + 1) ^ 2
(n + 1)
1
然后计算之间关系,构建矩阵(直接看代码里吧)
这题最难受的是我的数组开大了,导致我时间复杂度直接上了10倍,TLE了两发·······在初始化矩阵时。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
typedef long long ll;
const int N = 10;
ll n, p;
const ll mod = 2147493647;
ll a, b;
struct node {
ll g[N + 2][N + 2];//结构体存储矩阵
}f, res, s, rans;
//构造单位矩阵
void matrixI(node& x)
{
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= N; ++j)
{
if (i == j)x.g[i][j] = 1LL;
else x.g[i][j] = 0LL;
}
}
//矩阵乘法
void matrixMultiple(node& x, node& y, node& z)
{
memset(z.g, 0, sizeof(z.g));
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= N; ++j)
for (int k = 1; k <= N; ++k)
{
z.g[i][k] += (x.g[i][j] * y.g[j][k]) % mod;
if (z.g[i][k] >= mod)z.g[i][k] %= mod;
}
}
//快速幂
void matrixMuli(ll k)
{
matrixI(res);
node tmp = f, t;
while (k)
{
if (k & 1)
{
matrixMultiple(res, tmp, t);
res = t;
}
matrixMultiple(tmp, tmp, t);
tmp = t;
k >>= 1;
}
}
void init()
{
f.g[1][1] = 1; f.g[1][2] = 2; f.g[1][3] = 1;
f.g[2][1] = 1;
f.g[3][3] = 1; f.g[3][4] = 4; f.g[3][5] = 6; f.g[3][6] = 4; f.g[3][7] = 1;
f.g[4][4] = 1; f.g[4][5] = 3; f.g[4][6] = 3; f.g[4][7] = 1;
f.g[5][5] = 1; f.g[5][6] = 2; f.g[5][7] = 1;
f.g[6][6] = 1; f.g[6][7] = 1;
f.g[7][7] = 1;
}
ll solve()
{
ll ans;
if (n == 1)
ans = a % mod;
else if (n == 2)
ans = b % mod;
else
{
matrixMuli(n - 2);
ans = (s.g[1][1] * res.g[1][1] % mod + s.g[2][1] * res.g[1][2] % mod + s.g[3][1] * res.g[1][3] % mod + s.g[4][1] * res.g[1][4] % mod + s.g[5][1] * res.g[1][5] % mod + s.g[6][1] * res.g[1][6] % mod + s.g[7][1] * res.g[1][7] % mod) % mod;
}
return ans;
}
int main()
{
ll t;
scanf("%lld", &t);
init();
while (t--)
{
scanf("%lld%lld%lld", &n, &a, &b);
//memset(f.g, 0, sizeof(f.g));
//memset(res.g, 0, sizeof(res.g));
//memset(s.g, 0, sizeof(s.g));
//memset(rans.g, 0, sizeof(rans.g));
s.g[1][1] = b;
s.g[2][1] = a;
s.g[3][1] = 3 * 3 * 3 * 3;
s.g[4][1] = 3 * 3 * 3;
s.g[5][1] = 3 * 3;
s.g[6][1] = 3;
s.g[7][1] = 1;
ll ans = solve();
printf("%lld\n", ans);
}
return 0;
}