NOJ 1019 Fibonacci II

来源:互联网 发布:永久域名发布网器 编辑:程序博客网 时间:2024/05/22 02:28

题目大意

题目链接:http://acm.nit.net.cn/showproblem.jsp?pid=1019

 

求第n个斐波那契数列对m求余的值。

题目分析

题目类型:矩阵乘法、分治、数据结构。

 

题目分析:n可能很大,而且不知道m是多少,F(n)可能超过64位,所以不能先储存好再算。同样如果每次输入一次都计算一次的话,计算次数会很多,会超时。这是就想到斐波那契数列的另一种表现形式:矩阵形式。这样完成了加法到乘法的转变,但是速度还没优化。这时想到一个Olog(n))算法:分治,这样时间就不会超,题目就解决了。

通过代码

Ac Code:
  1. # include "stdio.h"   
  2.   
  3. int m;   
  4.   
  5. typedef struct  
  6.   
  7. {   
  8.   
  9.      int r11,r12,r21,r22;   
  10.   
  11. }mue;   
  12.   
  13. mue mul(mue a,mue b)   
  14.   
  15. {   
  16.   
  17.      mue c;   
  18.   
  19.      c.r11=(a.r11*b.r11+a.r12*b.r21)%m;   
  20.   
  21.      c.r12=(a.r11*b.r12+a.r12*b.r22)%m;   
  22.   
  23.      c.r21=(a.r21*b.r11+a.r22*b.r21)%m;   
  24.   
  25.      c.r22=(a.r21*b.r12+a.r22*b.r22)%m;   
  26.   
  27.      return c;   
  28.   
  29. }   
  30.   
  31. mue fib(mue a,int n)   
  32.   
  33. {   
  34.   
  35.      mue r;   
  36.   
  37.      if(n==0) { r.r11=1,r.r12=0,r.r21=0,r.r22=1; return r;}   
  38.   
  39.      if(n==1) { return a;}   
  40.   
  41.      if(n%2) { return mul(fib(mul(a,a),n/2),a);}   
  42.   
  43.      else return fib(mul(a,a),n/2);   
  44.   
  45. }   
  46.   
  47. int main ()   
  48.   
  49. {   
  50.   
  51.      int n;   
  52.   
  53.      while(scanf("%d%d",&n,&m)!=-1)   
  54.   
  55.      {   
  56.   
  57.          mue r;   
  58.   
  59.          r.r11=1,r.r12=1,r.r21=1,r.r22=0;   
  60.   
  61.          r=fib(r,n-1);   
  62.   
  63.          printf("%d/n",r.r11);   
  64.   
  65.      }   
  66.   
  67.      return 0;   
  68.   
  69. }   

原创粉丝点击