zoukankan      html  css  js  c++  java
  • hdu 4549 矩阵快速幂+费马小定理

    题目:
    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取模后的值即可,每组数据输出一行。
    分析:
    写一下f2,f3,f4,可以推出一个公式 F[n]=a^fib(n)*b^fib(n-1),a,b的系数是斐波那契数列,斐波那契数列的求法上几篇写过一个,应该是poj 3070那题吧,但是怎么取模呢?这就要用到费马小定理了,a^(p-1)=1mod(p),这题p是质数。所以求fib(n)的时候mod(p-1)就行。求出来fib(n)和fib(n-1)来了,然后快速幂求一下F(n)就行了。

    #include<cstdio>
    #include<cstring>
    typedef long long ll;
    const int mod=1e9+7;
    const int mo=1e9+6;
    struct Mat{
        ll mat[2][2];
    };
    Mat mul(Mat a,Mat b)
    {
        Mat c; memset(c.mat,0,sizeof(c.mat));
        for(int k=0;k<2;k++)
            for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
            c.mat[i][j]+=(a.mat[i][k]*b.mat[k][j])%mo;
        return c;
    }
    Mat qmo(Mat a,int k)
    {
        Mat c;
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
            c.mat[i][j]=(i==j);
        for(;k;k>>=1){
            if(k&1)c=mul(c,a);
            a=mul(a,a);
        }
        return c;
    }
    ll qmod(ll a,ll n)
    {
        ll ans=1;
        for(;n;n>>=1){
            if(n&1)ans=ans*a%mod;
            a=a*a%mod;
        }
        return ans;
    }
    int main()
    {
        int aa,bb,n;
        while(~scanf("%d%d%d",&aa,&bb,&n)){
            Mat a;
            a.mat[0][0]=a.mat[0][1]=a.mat[1][0]=1;a.mat[1][1]=0;
            Mat c=qmo(a,n);
            int ans=qmod(aa%mod,c.mat[1][1])*qmod(bb%mod,c.mat[0][1])%mod;
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    人生中对我影响最大的三位老师
    自我介绍
    对我影响较大的三位老师
    自我介绍
    Java入门到精通——基础篇之static关键字
    天猫优惠券面值可以随意修改
    常用的PC/SC接口函数
    批量删除本地指定扩展名文件工具
    算法:C++排列组合
    Java入门到精通——基础篇之面向对象
  • 原文地址:https://www.cnblogs.com/01world/p/5651254.html
Copyright © 2011-2022 走看看