这道题, 给我的最大的知识点就是对于去模运算,一定可以找到循环节,这题只不过是嵌套了两层,可以分别找到循环节。关于这题如何找循环节的,直接暴力,网上也有很多。
找到循环节之后,另一个知识点就是对于线性关系可以使用矩阵快速幂来加速。
附上代码:
/*************************************************************************
> File Name: 4292.cpp
> Author: Stomach_ache
> Mail: 1179998621@qq.com
> Created Time: 2014年04月20日 星期日 22时06分59秒
> Propose:
************************************************************************/
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <fstream>
using namespace std;
#define MOD1 (1000000007)
#define MOD2 (222222224)
#define MOD3 (183120)
typedef long long LL;
struct Matrix {
LL a[2][2];
//Matrix(int m):n(m){memset(a, 0, sizeof(a));}
inline Matrix multiply(Matrix& y, LL mod) {
Matrix ret;
for (LL i = 0; i < 2; i++) {
for (LL j = 0; j < 2; j++) {
LL tmp = 0;
for (LL k = 0; k < 2; k++) {
tmp = (tmp+a[i][k]*y.a[k][j])%mod;
//ret.a[i][j] = (ret.a[i][j]+tmp)%mod;
}
ret.a[i][j] = tmp;
}
}
return ret;
}
};
Matrix power_mod(Matrix x, LL y, LL mod) {
Matrix ans;
ans.a[0][0] = ans.a[1][1] = 1;
ans.a[0][1] = ans.a[1][0] = 0;
while (y) {
if (y % 2) {
ans = ans.multiply(x, mod);
}
x = x.multiply(x, mod);
y /= 2;
}
return ans;
}
int main(void) {
Matrix A;
A.a[0][0] = 0;
A.a[1][0] = 1;
A.a[0][1] = 1;
A.a[1][1] = 3;
LL n;
while (cin >> n) {
if (n == 0 || n == 1) {
cout << n << endl;
continue;
}
Matrix tmp1 = power_mod(A, n-1, MOD3);
n = tmp1.a[1][1];
if (n != 0 && n != 1) {
tmp1 = power_mod(A, n-1, MOD2);
n = tmp1.a[1][1];
}
if (n != 0 && n != 1) {
tmp1 = power_mod(A, n-1, MOD1);
n = tmp1.a[1][1];
}
cout << n << endl;
}
return 0;
}