题目链接:
http://acm.split.hdu.edu.cn/showproblem.php?pid=4549
题目大意:
已知a,b,n,接下来求解第n项的值。
题目思路:
已知a和b的指数是按照斐波那契数列的顺序进行递增的,所以只要求出a,b的指数即可。
费马小定理:如果p为质数且a,p互质 a^(p-1) = 1(mod p)
所以 a^n = a^( n%(p-1) ) * 1 * 1...
A^n%p 这题的p是质素,而且A,p是互质的。
所以直接A^(n%(p-1)) %p
坑点:
在这里矩阵快速幂mod的是p-1所以你在快速幂里写的mod值要为p-1(这个地方没发现,一直傻傻的写着p,wa到死)。
碰到斐波那契要想到矩阵快速幂,遇到质数之类的求膜要想到费马欧拉等定理及引理。
代码:
#include <bits/stdc++.h>
using namespace std;
const int mo = 1000000007;
const int size = 2;
#define ll long long
struct matrix
{
ll m[size][size];
};
matrix mul(matrix a,matrix b)
{
matrix c;
memset(c.m,0,sizeof(c.m));
for(int i=0;i<size;i++)
for(int j=0;j<size;j++)
for(int k=0;k<size;k++)
c.m[i][j] = ((a.m[i][k]*b.m[k][j])%(mo-1)+c.m[i][j])%(mo-1);//矩阵快速幂的模要搞清楚
return c;
}
matrix quick(matrix a,ll n)
{
matrix res;
memset(res.m,0,sizeof(res.m));
for(int i=0;i<size;i++) res.m[i][i]=1;
while(n){
if(n&1) res=mul(res,a);
n>>=1;
a=mul(a,a);
}
return res;
}
ll quickmo(ll a,ll b,ll p)
{
ll ans=1;
ll tmp = a%p;
while(b){
if(b&1) ans = ans*tmp%p;
tmp = tmp*tmp%p;
b>>=1;
}
return ans;
}
int main()
{
matrix p;
memset(p.m,0,sizeof(p.m));
p.m[0][1]=p.m[0][0]=p.m[1][0]=1;
ll a,b,n;
while(~scanf("%lld%lld%lld",&a,&b,&n)){
if(n==0) printf("%d\n",a);
else if(n==1) printf("%lld\n",b);
else if(n==2) printf("%lld\n",a*b%mo);
else{
matrix ans = quick(p,n-3);
ll z1 = (ans.m[0][0]*2+ans.m[0][1]*1)%(mo-1);//这里也要满足费马小定理的要求mo-1
ll z2 = (ans.m[1][0]*2+ans.m[1][1]*1)%(mo-1);
ll ans1=quickmo(a%mo,z2,mo)%mo;
ll ans2=quickmo(b%mo,z1,mo)%mo;
printf("%lld\n",ans1*ans2%mo);
}
}
}