HDU 1005 Number Sequence
题目大意:
\(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\times7=49\)种,只要找到\(f(n)\)和\(f(n-1)\)都是\(1\)的情况,就可以知道这个数列循环的周期。
为了训练矩阵快速幂,所以选择用矩阵快速幂来做这道题。
由递推公式构建矩阵:
\[ \left(
\begin{matrix}
f(n-1) & f(n-2)
\end{matrix}
\right)\times
\left(
\begin{matrix}
a & 1 \\
b & 0
\end{matrix}
\right)=
\left(
\begin{matrix}
f(n) & f(n-1)
\end{matrix}
\right)
\]
通过矩阵快速幂和矩阵乘法得到\(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;
}