用了提取大数前四位和矩阵快速幂。
/*矩阵快速幂*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
//const int mod = 10000;
typedef long long LL;
const int maxn = 20;
const int M[maxn+5] = {1, 10, 100, 1000, 10000};
LL mod;
int N = 40;
int fib[45];
struct Matrix {
LL mat[maxn][maxn];
int x, y;
Matrix() {
memset(mat, 0, sizeof(mat));
for (int i = 1; i <= maxn - 5; i++)
mat[i][i] = 1;
}
};
void maketable()
{
fib[0] = 0;
fib[1] = 1;
for(int i = 2; i < N; i++)
fib[i] = fib[i - 2] + fib[i - 1];
}
inline void mat_mul(Matrix a, Matrix b, Matrix &c) {
memset(c.mat, 0, sizeof(c.mat));
c.x = a.x; c.y = b.y;
/* for (int i = 1; i <= c.x; i++) {
for (int j = 1; j <= c.y; j++) {
for (int k = 1; k <= a.y; k++) {
c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod;
c.mat[i][j] %= mod;
}
}
}
*/
//仅适用于2*2
for (int i = 1; i <= 2; i++)
for (int j = 1; j <= 2; j++)
c.mat[i][j] = (a.mat[i][1] * b.mat[1][j] + a.mat[i][2] * b.mat[2][j]) % mod;
return ;
}
//快速幂
inline void mat_pow(Matrix &a, int z) {
Matrix ans, base = a;
ans.x = a.x; ans.y = a.y;
while (z) {
if (z & 1 == 1) mat_mul(ans, base, ans);
mat_mul(base, base, base);
z >>= 1;
}
a = ans;
}
int main() {
maketable();
/* int t;
cin >> t;*/
LL a, b, n, m;
while(~scanf("%lld", &n))
{
a = 0, b = 1;
Matrix A, B;
A.x = 2; A.y = 2;
A.mat[1][1] = 1; A.mat[1][2] = 1;
A.mat[2][1] = 1; A.mat[2][2] = 0;
B.x = 2; B.y = 1;
B.mat[1][1] = b; B.mat[2][1] = a;
if(n < N){
/*
mod = 1;
mat_pow(A, n - 1);
mat_mul(A, B, B);
printf("%lld\n", B.mat[1][1]);*/
cout << fib[n] << endl;
continue;
}
else {
double x = log10(1 / sqrt(5)) + n * log10((1 + sqrt(5)) / 2.0);
double y = x - (int)(x) + 3;
int ans = (int)pow(10.0, y);
cout << ans << "...";
mod = 10000;
mat_pow(A, n - 1);
mat_mul(A, B, B);
printf("%04d\n", B.mat[1][1]);
}
}
return 0;
}