• M斐波那契数列(矩阵快速幂+费马小定理)


    M斐波那契数列

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 1672    Accepted Submission(s): 482


    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
     

     

    题意:不解释,中文题。

    思路:费马小定理+矩阵快速幂

     

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4549 

    转载请注明出处:寻找&星空の孩子

    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define LL __int64
    const __int64 mod=1000000007;
    
    
    struct matrix
    {
        LL mat[2][2];
    };
    matrix multiply(matrix a,matrix b)
    {
        matrix c;
        memset(c.mat,0,sizeof(c.mat));
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<2;j++)
            {
                if(a.mat[i][j]==0)continue;
                for(int k=0;k<2;k++)
                {
                    if(b.mat[j][k]==0)continue;
                    c.mat[i][k]=(c.mat[i][k]+a.mat[i][j]*b.mat[j][k])%(mod-1);//加法不能简写成..+=...%..
                }
            }
        }
        return c;
    }
    matrix matrixquicklymod(matrix x,LL m)
    {
        matrix res;
    //    memset(res.mat,0,sizeof(res.mat));
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                res.mat[i][j]=(i==j);
        while(m)
        {
            if(m&1) res=multiply(res,x);
            m>>=1;
            x=multiply(x,x);
        }
        return res;
    }
    
    LL qmod(LL x, LL y)
    {
        LL z=1;
        while(y)
        {
            if(y&1) z=(z*x)%mod;
            y>>=1;
            x=(x*x)%mod;
        }
        return z;
    }
    int main()
    {
        LL a,b,n,ma,mb;
        while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF)
        {
            matrix ans;
            ma=mb=1;//
            ans.mat[0][0]=1;
            ans.mat[0][1]=1;
            ans.mat[1][0]=1;
            ans.mat[1][1]=0;
            if(n==0)
                printf("%I64d
    ",a%mod);
            else if(n==1)
                printf("%I64d
    ",b%mod);
            else if(n==2)
                printf("%I64d
    ",((a%mod)*(b%mod))%mod);
            else
            {
                ans=matrixquicklymod(ans,n-2);
                mb=ans.mat[0][0]+ans.mat[1][0];
                ma=ans.mat[0][1]+ans.mat[1][1];
                ma=ma%(mod-1);
                mb=mb%(mod-1);
                a=qmod(a,ma);
                b=qmod(b,mb);
                printf("%I64d
    ",((a%mod)*(b%mod))%mod);
            }
        }
        return 0;
    }

    慢慢提升吧。。。。。少年!

  • 相关阅读:
    GitLab基本用法
    SSH免密登录详解
    一文搞懂GitLab安装部署及服务配置
    初识:LevelDB
    Jenkins安装与Gitlab项目部署详解
    CentOS7的安装和配置
    C/C++语言的学习方向
    C语言atoi函数
    C语言整数的取值范围
    C语言scanf函数
  • 原文地址:https://www.cnblogs.com/yuyixingkong/p/4335905.html
Copyright © 2020-2023  润新知