题解
题目大意,给定一个递推式要求求出递推式的第n项,n <= 1e9。
题目是可以用矩阵快速幂直接log复杂度求出,但是麻烦啊。。所以以下代码使用找循环节的方法。
递推式由前两项构成,每项都进行%7运算,取模之后范围0~6共7种,前两项最多有7*7=49种组合。所以在49+49个范围内一定能找到循环节(可能是混循环)。
递推得到前200项目(少点也行)。枚举循环节开始位置i,循环节终点j,只判断三位如果三位都相等则必然出现循环。
最后将n减去循环出现位置i,对循环节长度取模输出对应项即可。
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 200;
int f[N];
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
int a, b, n;
while (scanf("%d%d%d", &a, &b, &n), a || b || n)
{
f[1] = f[2] = 1;
for (int i = 3; i < N; ++i)
f[i] = (f[i - 1] * a + f[i - 2] * b) % 7;
if (n < N)
{
cout << f[n] << endl;
continue;
}
/*
for (int i = 0; i < 47; ++i)
printf("%d ", f[i + 1]);
cout << endl;
for (int i = 47; i < 47 * 2; ++i)
printf("%d ", f[i + 1]);
cout << endl;
*/
bool lop = 1;
for (int i = 0; i < 50 && lop; ++i) //找到循环起点
for (int j = i + 1; j < 100 && lop; ++j) //下一个循环节
{
int flag = 1;
for (int k = 0; k < 3; ++k)
if (f[i + k] != f[j + k])
flag = 0;
if (flag)
{
n = i + (n - i) % (i - j);
printf("%d\n", f[n]);
lop = 0;
}
}
}
return 0;
}