题目:
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1126
题意:
有一个序列是这样定义的:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
给出A,B和N,求f(n)的值。
Input
输入3个数:A,B,N。数字之间用空格分割。(-10000 <= A, B <= 10000, 1 <= N <= 10^9)
Output
输出f(n)的值。
思路
矩阵快速幂裸题,首先构造一个2*2的矩阵,矩阵元素从左至右从上至下分别是 a 1 b 0,求这个矩阵的n-2次幂,然后构造一个1*2的矩阵,元素分别是f(2) f(1),把这个矩阵与之前求得的幂相乘,得到的结果中第一行第一列的元素就是答案
#include <bits/stdc++.h>
using namespace std;
const int N = 10 + 10, MOD = 7;
struct matrix
{
int row, col;
int mat[N][N];
matrix(int _row=0, int _col=0)
{
init(_row, _col);
}
void init(int _row, int _col)
{
row = _row, col = _col;
memset(mat, 0, sizeof mat);
}
matrix operator* (matrix b)
{
matrix c(row, b.col);
for(int i = 1; i <= row; i++)
for(int j = 1; j <= b.col; j++)
for(int k = 1; k <= col; k++)
c.mat[i][j] = (c.mat[i][j] + mat[i][k] * b.mat[k][j] % MOD + MOD) % MOD;
return c;
}
};
matrix matrix_pow(matrix a, int b)
{
matrix ans(a.row, a.col);
ans.mat[1][1] = ans.mat[2][2] = 1;
while(b)
{
if(b & 1) ans = ans * a;
b >>= 1;
a = a * a;
}
return ans;
}
int main()
{
int a, b, n;
scanf("%d%d%d", &a, &b, &n);
if(n <= 2) printf("%d\n", 1);
else
{
matrix arr(2, 2);
arr.mat[1][1] = a, arr.mat[2][1] = b;
arr.mat[1][2] = 1, arr.mat[2][2] = 0;
matrix brr(1, 2);
brr.mat[1][1] = 1, brr.mat[1][2] = 1;
arr = matrix_pow(arr, n - 2);
brr = brr * arr;
printf("%d\n", brr.mat[1][1]);
}
return 0;
}