NBUT-2014暑期集训专题练习1 -> 二分法 H - H

Description

In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn ? 1 + Fn ? 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

An alternative formula for the Fibonacci sequence is

NBUT-2014暑期集训专题练习1 - 二分法 H - H - 深海灬孤独 - Alex.

Given an integer n, your goal is to compute the last 4 digits of Fn.

Input

The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number ?1.

Output

For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).

Sample Input

0
9
999999999
1000000000
-1

Sample Output

0
34
626
6875

本题是矩阵快速幂的题,放在二分专题里就是因为计算高次幂的时候是需要用到二分的思想的

简单介绍下快速幂,例如A^156次,如果直接去计算,耗时太多,但是,将其分解就会看到A^156=(A^128)*(A^16)*(A^8)*(A^4),而128,16,8,4又恰好是二进制每一位1的权值,所以我们利用这个思想,从右向左判断一个数的某一位是否是1,如果是,则进行相乘,之后将n减小1倍。

给出伪代码

  while(n不为0)

{

  if(n当前最后一位是1)

{

   res=res*A;

}

n除以2;

A=A*A;;

}


基本上就是二进制思想,然后去/2 /2 /2.....


#include<stdio.h>
#include<string.h>

struct node
{
int mat[2][2];
}res,old;


node mutiply(node a,node b)
{
node c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
c.mat[i][j]=0;
for(int k=0;k<2;k++)
{
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
c.mat[i][j]%=10000;
}
}
return c;
}
int main()
{
__int64 n;
while(~scanf("%I64d",&n))
{
if(n==-1)
break;
old.mat[0][0]=1;
old.mat[0][1]=1;
old.mat[1][0]=1;
old.mat[1][1]=0;
res.mat[0][0]=1;
res.mat[1][1]=1;
res.mat[0][1]=0;
res.mat[1][0]=0;
if(n==0)
printf("0\n");
else
{
while(n)
{
if(n&1)
{
res=mutiply(res,old);
}
n>>=1;
old=mutiply(old,old);
}
printf("%d\n",res.mat[1][0]%10000 );
}
}
return 0;
}


你可能感兴趣的:(NBUT-2014暑期集训专题练习1 -> 二分法 H - H)