题目大意:
(f(1)=1,f(2)=1,f(n)=(A*f(n-1)+B*f(n-2))\%7),
给出(A),(B),(N)求出(f(N))。
题解:
可以通过找规律的方法解决这道题,由于(f(n))要模(7),所以只有(0)~(6)七种情况,而(f(n))和(f(n-1))的组合情况就只有(7 imes7=49)种,只要找到(f(n))和(f(n-1))都是(1)的情况,就可以知道这个数列循环的周期。
为了训练矩阵快速幂,所以选择用矩阵快速幂来做这道题。
由递推公式构建矩阵:
[ left(
egin{matrix}
f(n-1) & f(n-2)
end{matrix}
ight) imes
left(
egin{matrix}
a & 1 \
b & 0
end{matrix}
ight)=
left(
egin{matrix}
f(n) & f(n-1)
end{matrix}
ight)
]
通过矩阵快速幂和矩阵乘法得到(f(n))。
#include <iostream>
#include <cstring>
using namespace std;
#define ms(a, b) memset(a, b, sizeof(a))
#define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define N 2
const int mod = 7;
int a, b, n;
struct Matrix {
int num[N][N];
};
Matrix multi(Matrix a, Matrix b) {
Matrix c;
ms(c.num, 0);
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
for (int k = 0; k < N; ++k) {
c.num[i][j] += a.num[i][k] * b.num[k][j];
c.num[i][j] %= mod;
}
}
}
return c;
}
Matrix fastPow(Matrix x, int k) {
Matrix res;
ms(res.num, 0);
for (int i = 0; i < N; ++i) {
res.num[i][i] = 1;
}
while (k) {
if (k & 1) {
res = multi(res, x);
}
x = multi(x, x);
k >>= 1;
}
return res;
}
int main() {
io_speed_up;
while (cin >> a >> b >> n) {
if (!a && !b && !n) {
break;
}
Matrix temp;
temp.num[0][0] = a;
temp.num[0][1] = 1;
temp.num[1][0] = b;
temp.num[1][1] = 0;
temp = fastPow(temp, n - 1);
cout << (temp.num[0][1] + temp.num[1][1]) % mod << endl;
}
return 0;
}
P.S. 如果将矩阵快速幂代码写成如下,会不知为何而超时。
temp = fastPow(temp, n - 2);
cout << (temp.num[0][0] + temp.num[1][0]) % mod << endl;