您的位置:首页 > 其它

hdu 4549 M斐波那契数列

2014-11-19 20:47 267 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4549

思路:

观察a,b的幂符合斐波那契数列,因为n特别的大,所以构造矩阵求出a,b的第n的幂。 构造矩阵之后矩阵快速幂,因为在快速幂的时候矩阵相乘会超出__int64。所以需要用到一个定理

当gcd(a,mod)==1的时候
a^x = a^( x mod Eular(mod) ) ( mod mod ) . 所以变成这样a^b%mod=a^(b%(mod-1))%mod;

#include <cstdio>
#include<cstring>
#include <algorithm>
#define LL __int64
using namespace std;
const int mod=1e9+7;

LL a,b,n;

struct node
{
LL a[4][4];
};

node mul(node x,node y)
{
node c;
for(int i=0; i<2; i++)
{
for(int j=0; j<2; j++)
{
c.a[i][j]=0;
for(int k=0; k<2; k++)
{
c.a[i][j]+=x.a[i][k]*y.a[k][j];
c.a[i][j]%=(mod-1);
}
}
}
return c;
}

node pow_m(node c,int n)
{
node temp;
memset(temp.a,0,sizeof(temp.a));
temp.a[0][0]=1; temp.a[1][1]=1;
node xx=c;
while(n)
{
if(n&1) temp=mul(temp,xx);
xx=mul(xx,xx);
n>>=1;
}
return temp;
}

LL pow_M(LL a,LL n)
{
LL ans=1;
LL temp=a%mod;
while(n)
{
if(n&1)
{
ans*=temp;
ans%=mod;
}
temp*=temp;
temp%=mod;
n>>=1;
}
return ans;
}

int main()
{
node tem;
tem.a[0][0]=0; tem.a[0][1]=1;
tem.a[1][0]=tem.a[1][1]=1;
while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF)
{
node st=pow_m(tem,n);
printf("%I64d\n",(pow_M(a,st.a[0][0])*pow_M(b,st.a[1][0]))%mod);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: