[hdu 5950 Recursive sequence] 矩阵快速幂
题目链接:[hdu 5950 Recursive sequence]
题意描述:已知通项公式
Fi=Fi−1+2∗Fi−2+i4
, 并且已知
F1=a,F2=b
和一个数字
n
,求
解题思路:
显然的矩阵快速幂。
需要维护的值有
Fi−1,Fi−2,n4,n3,n2,n,1
这七个变量。维护红色变量的原因是方便求出
(n+1)4
。
然后构造矩阵就可以了。
#include <bits/stdc++.h>
using namespace std;
typedef __int64 LL;
const LL MOD = 2147493647;
LL T, N, A, B;
struct Mat {
static const int MSZ = 7;
LL m[MSZ][MSZ];
void O() { memset(m, 0, sizeof(m)); }
void E() {
O();
for(int i = 0; i < MSZ; i++) m[i][i] = 1;
}
void assign(LL ar[MSZ][MSZ]) {
for(int i = 0; i < MSZ; i++) {
for(int j = 0; j < MSZ; j++) {
m[i][j] = ar[i][j];
}
}
}
Mat operator * (const Mat& e) const {
Mat ret; ret.O();
for(int k = 0; k < MSZ; k++) {
for(int i = 0; i < MSZ; i++) {
if(m[i][k] == 0) continue;
for(int j = 0; j < MSZ; j++) {
ret.m[i][j] += m[i][k] * e.m[k][j] % MOD;
ret.m[i][j] %= MOD;
}
}
}
return ret;
}
Mat operator ^ (LL b) const {
Mat ret, a(*this); ret.E();
while(b > 0) {
if(b & 1) ret = ret * a;
a = a * a;
b >>= 1;
}
return ret;
}
} tras, init, res;
int main() {
// freopen("input.txt", "r", stdin);
// 变换矩阵
LL x[][Mat::MSZ] = {
{1, 2, 1, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 4, 6, 4, 1},
{0, 0, 0, 1, 3, 3, 1},
{0, 0, 0, 0, 1, 2, 1},
{0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 1}
};
tras.assign(x);
cin >> T;
while(T --) {
cin >> N >> A >> B;
if(N == 1) {
cout << A % MOD << "\n";
continue;
}
if(N == 2) {
cout << B % MOD << "\n";
continue;
}
// 初始矩阵
LL y[][Mat::MSZ] = {
{B, 0, 0, 0, 0, 0, 0},
{A, 0, 0, 0, 0, 0, 0},
{81, 0, 0, 0, 0, 0, 0},
{27, 0, 0, 0, 0, 0, 0},
{9, 0, 0, 0, 0, 0, 0},
{3, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0}
};
init.assign(y);
res = tras ^ (N - 2);
res = res * init;
cout << res.m[0][0] << endl;
}
return 0;
}