求斐波那契的前后4位,n <= 10^8.
思路:
至于前四位,和hdu1568的求法一样:
http://blog.csdn.net/u013761036/article/details/38726907
后四位也很好求,后四位我们可以用矩阵+快速幂去求,斐波那契的矩阵
很好推
x0 x1 * 0 1 = x1 x2
1 1
这样就直接ok了,后四位直接在跑矩阵的时候对10000取余就行了。
#include<stdio.h> #include<string.h> #include<math.h> typedef struct { __int64 mat[3][3]; }A; A mat_mat(A a ,A b) { A c; memset(c.mat ,0 ,sizeof(c.mat)); for(int k = 1 ;k <= 2 ;k ++) for(int i = 1 ;i <= 2 ;i ++) if(a.mat[i][k]) for(int j = 1 ;j <= 2 ;j ++) { c.mat[i][j] += (a.mat[i][k]) * (b.mat[k][j]); c.mat[i][j] %= 10000; } return c; } A quick_mat(A a ,int b) { A c; memset(c.mat ,0 ,sizeof(c.mat)); for(int i = 1 ;i <= 2 ;i ++) c.mat[i][i] = 1; while(b) { if(b&1) c = mat_mat(c ,a); a = mat_mat(a ,a); b >>= 1; } return c; } int num[40]; void ini() { num[0] = 0 ,num[1] = 1; for(int i = 2 ;i<= 39 ;i ++) num[i] = num[i-1] + num[i-2]; } int main () { ini(); int n; A aa; while(~scanf("%d" ,&n)) { if(n <= 39) { printf("%d " ,num[n]); continue; } double now = -0.5 * log10(5.0) + n * 1.0 * log10((1+sqrt(5.0))/2); double bit = now - int(now); int a = int(pow(10.0 ,bit) * 1000); aa.mat[1][1] = 0; aa.mat[2][1] = aa.mat[1][2] = aa.mat[2][2] = 1; aa = quick_mat(aa ,n); int b = 0 * aa.mat[1][1] + 1 * aa.mat[2][1]; printf("%d...%04d " ,a ,b); } return 0; }