<a target=_blank href="http://poj.org/problem?id=3070">点击打开链接</a>
本题求第n项
Fibonacci 数的后四位,由于n的范围到10^9,用矩阵相乘可以实现,如上图。但我们只需要两项,因此初始化矩阵{ 1 1 0 0 } 而后 n-1个 {1 1 1 0} 矩阵相乘,当然要用快速幂才能不超时,快速幂即如2^16,有2^8*2^8,而2^8 =
2^4*2^4,而2^4 = 2 * 2,可见每次减半相乘,次数减少很多,当然遇到奇数次,如2^5
只需变为 2*1*2^2*2^2 即可。
而矩阵则乘单位矩阵。
#include
#include
using namespace std;
/*定义结构体*/
struct matirx
{
int fi[2][2];
};
matirx a,b,temp;
/*矩阵乘法*/
matirx mul(matirx c,matirx d)
{
matirx s;
int i,j,k;
for(i = 0; i < 2; i++)
for(j = 0;j < 2; j++){
s.fi[i][j] = 0;
for(k = 0; k < 2; k++)
s.fi[i][j] += c.fi[i][k]*d.fi[k][j];
s.fi[i][j] %=10000;/*取模*/
}
return s;
}
/*快速幂*/
matirx quick_mode(int n)
{
matirx q = temp;/*temp 为单位矩阵*/
matirx p = b;
n--;
while(n >= 1){
if(n%2)
q = mul(q,p);
n/=2;
p = mul(p,p);
}
q = mul(q,a);
return q;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF && n != -1)
{
int i,j;
if(n == 0)
printf("%d\n",0);
else {
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++){
if(i == 0)
a.fi[i][j] = 1;
else a.fi[i][j] = 0;
b.fi[i][j] = 1;
if(i == j)
temp.fi[i][j] = 1;
else temp.fi[i][j] = 0;
}
b.fi[1][1] = 0;
matirx m = quick_mode(n);
printf("%d\n",m.fi[0][1]);
}
}
return 0;
}