zoukankan      html  css  js  c++  java
  • HDU 4549 M斐波那契数列(矩阵快速幂+费马小定理)

    M斐波那契数列

    Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
    Total Submission(s) : 43   Accepted Submission(s) : 28

    Font: Times New Roman | Verdana | Georgia

    Font Size: ← →

    Problem Description

    M斐波那契数列F[n]是一种整数数列,它的定义如下:

    F[0] = a
    F[1] = b
    F[n] = F[n-1] * F[n-2] ( n > 1 )

    现在给出a, b, n,你能求出F[n]的值吗?

    Input

    输入包含多组测试数据;
    每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )

    Output

    对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。

    Sample Input

    0 1 0
    6 10 2

    Sample Output

    0
    60
    

    Source

    2013金山西山居创意游戏程序挑战赛——初赛(2)

     题解:

       题目中  f[n] =a ^? * b^? ,a,b的指数,刚好可以使用斐波那契数列求解,
       矩阵快速幂求斐波那契数列
     
      费马小定理:
        若p是质数,且gcd(a,p)=1,则  a ^ (p-1) = 1 (mod p)
     
    #include <iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int mod=1000000007;
    long long a,b;
    int n;
    long long pow(long long a,long long b)
    {
        long long res=1;
        while(b)
        {
            if (b&1) res=(res*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return res;
    }
    long long mul(int n)
    {
        long long t[2][2]={1,1,1,0};//相当于pow中的a
        long long ans[2][2]={1,0,0,1};//存最后的结果
        long long tmp[2][2]; // 临时的
        while(n)
        {
            if (n&1)
            {
                for(int i=0;i<2;i++)
                    for(int j=0;j<2;j++)
                      tmp[i][j]=ans[i][j],ans[i][j]=0;
                for(int i=0;i<2;i++)
                    for(int j=0;j<2;j++)
                        for(int k=0;k<2;k++)
                            ans[i][j]=(ans[i][j]+tmp[i][k]*t[k][j])%(mod-1);
            }
            for(int i=0;i<2;i++)
             for(int j=0;j<2;j++)
               { tmp[i][j]=t[i][j]; t[i][j]=0;}
            for(int i=0;i<2;i++)
                for(int j=0;j<2;j++)
                    for(int k=0;k<2;k++)
                      t[i][j]=(t[i][j]+tmp[i][k]*tmp[k][j])%(mod-1);
            n>>=1;
        }
      return (pow(a,ans[1][1])*pow(b,ans[1][0]))%mod;
    }
    int main()
    {
        while(~scanf("%lld%lld%d",&a,&b,&n))
        {
           if (n==0) printf("%lld
    ",a%mod);
            else if (n==1) printf("%lld
    ",b%mod);
             else printf("%lld
    ",mul(n));
        }
    
        return 0;
    }
  • 相关阅读:
    29 友盟大数据--flume源码查看分析ExecSource--UmengExecSource 改造exec源 :监控目录、收集新文件---增加个守护线程不断监控目录
    28 友盟大数据--flume源码查看分析- ExecSource-参照主机名拦截器HostInterceptor ---写限速拦截器
    Demo
    分布式爬虫-Kafka监控
    SQL优化
    MySQL
    Spring
    Mybatis
    类加载器
    数据仓库分层
  • 原文地址:https://www.cnblogs.com/stepping/p/7146301.html
Copyright © 2011-2022 走看看