题目概述
给定一个数列f,该数列符合如下公式
f(1) = 1, f(2) = 1, f(n) = (a * f(n - 1) + b * f(n - 2)) mod 7
其中a,b,n已知,求f(n)的值
输入
每行三个数,a,b,n,其意义如上所示,输入以三个0结束并忽略该组数据
限制
1<=a,b<=1000;1<=n<=1e8;
输出
每行一个数,f(n)
样例输入
1 1 1
1 2 10
1 1 2
1 1 3
1 1 6
1 1 7
2 3 1
2 3 2
2 3 3
2 3 4
0 0 0
样例输出
1
5
1
2
1
6
1
1
5
6
讨论
考察斐波那契数列的矩阵求法,并且简单的扩展了一下,要注意的地方莫过于几个需要求模的地方,以及应当如何处理a,b在矩阵中的位置
题解状态
0MS,1728K,1611 B,C++
题解代码
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<iostream>
#include<set>
#include<map>
#include<string>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
#define maxx(a,b) ((a)>(b)?(a):(b))
#define minn(a,b) ((a)<(b)?(a):(b))
#define MAXN 26
#define memset0(a) memset(a,0,sizeof(a))
struct matrix//2x2矩阵
{
int a0[2], a1[2];//矩阵的四个数
matrix()//默认构造二阶单位矩阵
{
a0[0] = 1;
a0[1] = 0;
a1[0] = 0;
a1[1] = 1;
}
matrix(int a, int b, int c, int d)
{
a0[0] = a;
a0[1] = b;
a1[0] = c;
a1[1] = d;
}
matrix operator*(matrix b)//矩阵乘法
{
matrix s;
s.a0[0] = a0[0] * b.a0[0] + a0[1] * b.a1[0];
s.a0[1] = a0[0] * b.a0[1] + a0[1] * b.a1[1];
s.a1[0] = a1[0] * b.a0[0] + a1[1] * b.a1[0];
s.a1[1] = a1[0] * b.a0[1] + a1[1] * b.a1[1];
return s;
}
matrix operator%(int b)//矩阵模
{
matrix s;
s.a0[0] = a0[0] % b;
s.a0[1] = a0[1] % b;
s.a1[0] = a1[0] % b;
s.a1[1] = a1[1] % b;
return s;
}
};
matrix qpow(matrix a, int n, int mod)//矩阵快速幂
{
if (!n)
return matrix();
else if (n == 1)
return a%mod;
else if (n % 2 == 1)
return ((qpow(a*a%mod, n / 2, mod) % mod)*(a%mod)) % mod;
else
return qpow(a*a%mod, n / 2, mod) % mod;
}
int fun(int a, int b, int n)
{
matrix s(1, 1, 1, 0);
matrix c(a, 1, b, 0);
c = qpow(c, n - 2, 7);
return (s*c).a0[0]%7;//注意这里也需要求模
}
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
//freopen("vs_cout.txt", "w", stdout);
int a, b, n;
while (~scanf("%d%d%d", &a, &b, &n) && (a || b || n)) {//input
if (n == 1 || n == 2)
printf("1\n");//output//前两个数必然为1 若进行计算 则f(2)可能不为1而出错
else
printf("%d\n", fun(a, b, n));//output
}
}
EOF