zoukankan      html  css  js  c++  java
  • poj 3070 Fibonacci(矩阵快速幂求Fibonacci数列)

    题目链接:

    http://poj.org/problem?id=3070

    题意:

    我们知道斐波那契数列0 1 1 2 3 5 8 13……

    数列中的第i位为第i-1位和第i-2位的和(规定第0位为0,第一位为1)。

    求斐波那契数列中的第n位mod 10000的值。

    思路:

    这里的n很大,有10^9,for一遍肯定是不可以的。

    所以要用矩阵乘法求斐波那契数列。

    f[n+1] = f[n]+f[n-1]

    f[n] = f[n]

    构造以下矩阵,n次幂,mat[1][0] 就是答案

    1 1

    1 0

    求矩阵乘法  用快速幂

    代码:

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <cstdio>
     5 using namespace std;
     6 typedef long long ll;
     7 #define MS(a) memset(a,0,sizeof(a))
     8 #define MP make_pair
     9 #define PB push_back
    10 const int INF = 0x3f3f3f3f;
    11 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
    12 inline ll read(){
    13     ll x=0,f=1;char ch=getchar();
    14     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    15     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 //////////////////////////////////////////////////////////////////////////
    19 const int maxn = 1e5+10;
    20 const int mod = 10000;
    21 
    22 struct mat{
    23     int at[2][2];
    24 };
    25 
    26 mat d;
    27 int n;
    28 
    29 mat mul(mat a,mat b){
    30     mat re;
    31     memset(re.at,0,sizeof(re.at));
    32     for(int i=0; i<n; i++)
    33         for(int k=0; k<n; k++)
    34             for(int j=0; j<n; j++)
    35                 re.at[i][j] = (re.at[i][j]+a.at[i][k]*b.at[k][j])%mod;
    36         
    37     return re;
    38 }
    39 
    40 mat expo(mat p,int k){
    41     if(k == 1) return p;
    42     mat e;
    43     memset(e.at,0,sizeof(e.at));
    44     for(int i=0; i<n; i++) { e.at[i][i]=1; }
    45     if(k == 0) return e;
    46     while(k){
    47         if(k&1) e = mul(p,e);
    48         p = mul(p,p);
    49         k >>= 1;
    50     }
    51     return e;
    52 }
    53 
    54 int main(){
    55     n = 2;
    56     d.at[1][1] = 0;
    57     d.at[0][0]=d.at[0][1]=d.at[1][0] = 1;
    58     int k;
    59     while(cin >> k){
    60         if(k == -1) break;
    61         mat res = expo(d,k);
    62         int ans = res.at[1][0]%mod;
    63         cout << ans << endl;
    64     }
    65 
    66     return 0;
    67 }



  • 相关阅读:
    LNMP源码安装配置
    CentOS6 Apache配置详解(上)
    CentOS6 Apache配置详解(中)
    BZOJ4152 AMPPZ2014 The Captain(最短路)
    BZOJ4028 HEOI2015公约数数列(分块)
    Codeforces Round #517 Div. 1翻车记
    BZOJ4027 HEOI2015兔子与樱花(贪心)
    BZOJ4000 TJOI2015棋盘(状压dp+矩阵快速幂)
    Codeforces Round #510 Div. 2 Virtual Participate记
    BZOJ5190 Usaco2018 Jan Stamp Painting(动态规划)
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6837356.html
Copyright © 2011-2022 走看看