算法提高 递推求值
时间限制:1.0s 内存限制:256.0MB
问题描述
已知递推公式:
F(n, 1)=F(n-1, 2) + 2F(n-3, 1) + 5,
F(n, 2)=F(n-1, 1) + 3F(n-3, 1) + 2F(n-3, 2) + 3.
初始值为:F(1, 1)=2, F(1, 2)=3, F(2, 1)=1, F(2, 2)=4, F(3, 1)=6, F(3, 2)=5。
输入n,输出F(n, 1)和F(n, 2),由于答案可能很大,你只需要输出答案除以99999999的余数。
输入格式
输入第一行包含一个整数n。
输出格式
输出两行,第一行为F(n, 1)除以99999999的余数,第二行为F(n, 2)除以99999999的余数。
样例输入
4
样例输出
14
21
数据规模和约定
1<=n<=10^18。
分析:用递归直接写是必定超时的,所以用矩阵快速幂来写。用结构体记录数组的内容和行数列数。有几个需要注意的地方:n的数据类型不能用int;初始的n = 1 - 4时需要单独输出。
代码:
#include<iostream>
#include<vector>
#define Mod 99999999
using namespace std;
struct M {
vector<vector<long long> > m;
int r;
int c;
M() {
}
M(int _r, int _c) {
r = _r;
c = _c;
m.resize(r);
for (int i = 0; i < r; i++) {
m[i].resize(c);
}
}
};
M matrixMul(M a, M b) {
M c = M(a.r, b.c);
for (int i = 0; i < a.r; i++) {
for (int j = 0; j < b.c; j++) {
for (int k = 0; k < a.c; k++) {
c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j]) % Mod;
}
}
}
for (int i = 0; i < c.c; i++) {
c.m[0][i] %= Mod;
}
return c;
}
int main() {
long long n;
cin >> n;
if (n == 1) {
cout << 2 << endl;
cout << 3 << endl;
} else if (n == 2) {
cout << 1 << endl;
cout << 4 << endl;
} else if (n == 3) {
cout << 6 << endl;
cout << 5 << endl;
} else {
n -= 3;
M A = M(1, 8);
A.m[0][0] = 6;
A.m[0][1] = 5;
A.m[0][2] = 1;
A.m[0][3] = 4;
A.m[0][4] = 2;
A.m[0][5] = 3;
A.m[0][6] = 5;
A.m[0][7] = 3;
M B = M(8, 8);
B.m[1][0] = 1; B.m[4][0] = 2; B.m[6][0] = 1;
B.m[0][1] = 1; B.m[4][1] = 3; B.m[5][1] = 2; B.m[7][1] = 1;
B.m[0][2] = 1;
B.m[1][3] = 1;
B.m[2][4] = 1;
B.m[3][5] = 1;
B.m[6][6] = 1;
B.m[7][7] = 1;
M Fn;
while (n) {
if (n & 1) {
Fn = matrixMul(A, B);
A = Fn;
}
B = matrixMul(B, B);
n >>= 1;
}
cout << Fn.m[0][0] << endl;
cout << Fn.m[0][1] << endl;
}
return 0;
}