BIT1047 Fibonacci Numbers

题目大意:求斐波那契数列的第n项对p取余的值(n,p<10^9)

 

考察点:数论

 

思路分析:参考了http://xuyemin520.is-programmer.com/posts/26398.html

构造一个2 x 2的矩阵,使得它乘以(a,b)得到的结果是(b,a+b)。每多乘一次这个矩阵,这两个数就会多迭代一次。那么,我们把这个2 x 2的矩阵自乘n次,再乘以(0,1)就可以得到第n个Fibonacci数了。不用多想,这个2 x 2的矩阵很容易构造出来:

 

接下来我们要做的就是将这个矩阵的(n-1)次幂算出来,再乘以初始矩阵 ,即(0 1)的转置就行了。

 

计算(n-1)次幂可以用快速幂

 

#include<stdio.h>

typedef struct juzhen{
        long long a,b,c,d;
}juzhen;

juzhen jzmul(juzhen x,juzhen y,long long p)
{
     juzhen t;
     t.a=((x.a*y.a)%p+(x.b*y.c)%p)%p;
     t.b=((x.a*y.b)%p+(x.b*y.d)%p)%p;
     t.c=((x.c*y.a)%p+(x.d*y.c)%p)%p;
     t.d=((x.c*y.b)%p+(x.d*y.d)%p)%p;
     return t;
}
int main()
{
    long long n,p;
    while (scanf("%lld%lld",&n,&p)!=EOF)
    {
          n=n-2;
          if (n==0) printf("1\n");
          else if (n==-1) printf("1\n");
          else if (n==-2) printf("0\n");
          else{
          juzhen q,ans;
          q.a=1;q.b=1;q.c=1;q.d=0;
          ans.a=1;ans.b=1;ans.c=1;ans.d=0;
          while (n>0)
          {
                if (n%2==1) ans=jzmul(ans,q,p);
                n=n/2;
                q=jzmul(q,q,p);
          }
          printf("%lld\n",ans.a);}
    }
    return 0;
}
          
          
    


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值