题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3117
分析:求第n个斐波那契数的前后各4位,对于求后4位,只需要矩阵连乘对10000取模即可,至于前4位呢,就是HDU1568的原型。需要注意的是,后4位对10000取模后如果高位为0,这个0不能省去。
实现代码如下:
#include <cstdio>
#include <math.h>
using namespace std;
const int mod=10000;
long long f[100];
typedef struct
{
long long m[2][2];
}matrix;
matrix I={1,0,0,1};
matrix P={0,1,1,1};
matrix mul(matrix a,matrix b)
{
matrix c;
int i,j,k;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
{
c.m[i][j]=0;
for(k=0;k<2;k++)
{
c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;
c.m[i][j]%=mod;
}
}
return c;
}
matrix quick_mod(long long n)
{
matrix m=P,b=I;
while(n>=1)
{
if(n&1)
b=mul(b,m);
n=n>>1;
m=mul(m,m);
}
return b;
}
int main()
{
double log_s=0.0;
matrix temp;
int i,n,bit=0;
f[0]=0;
f[1]=1;
for(i=2;i<=50;i++)
{
f[i]=f[i-1]+f[i-2];
if(f[i]>=100000000)
{
bit=i-1;
break;
}
}
while(scanf("%d",&n)!=-1)
{
if(n<=bit) printf("%lld\n",f[n]);
else
{
temp=quick_mod(n);
int tail=temp.m[0][1];
log_s=-0.5*log10(5.0)+(double)n*log10((1+sqrt(5.0))/2.0);
int head=(int)pow(10.0,(log_s+3-(int)log_s));
printf("%d...%04d\n",head,tail);
}
}
return 0;
}