这题的话,看a ,b 的指数,刚好可以使用斐波那契数列求解。
加法斐波那契数列是直接在最后用(b*m.mat[0][0] + a * m.mat[1][0] ) % MOD
乘法就变成了乘方!!所以需要用到快速模幂。。
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">然后用矩阵做。</span>
A^B %C 这题的C是质素,而且A,C是互质的。
所以直接A^(B%(C-1)) %C
比较一般的结论是 A^B %C=A^( B%phi(C)+phi(C) ) %C B>=phi(C)
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
using namespace std;
#define MOD 1000000007
#define N 2
struct Mat
{
long long mat[N][N];
};
Mat operator * (Mat a, Mat b)
{
Mat c;
memset(c.mat, 0, sizeof(c.mat));
int i, j, k;
for(k = 0; k < N; ++k)
{
for(i = 0; i < N; ++i)
{
if(a.mat[i][k] <= 0) continue; //(针对ZOJ2853)剪枝,cpu运算乘法的效率并不是想像的那么理想(加法的运算效率高于乘法,比如Strassen矩阵乘法)
for(j = 0; j < N; ++j)
{
if(b.mat[k][j] <= 0) continue; //剪枝
c.mat[i][j] = (c.mat[i][j] + (a.mat[i][k] * b.mat[k][j]) % (MOD - 1)) % (MOD - 1);
}
}
}
return c;
}
Mat operator ^ (Mat a, int k)
{
Mat c;
int i, j;
for(i = 0; i < N; ++i)
for(j = 0; j < N; ++j)
c.mat[i][j] = (i == j); //初始化为单位矩阵
for(; k; k >>= 1)
{
if(k&1) c = c*a;
a = a*a;
}
return c;
}
long long Pow(long long n ,long long m, int mod)
{
long long res = 1;
while(m >= 1)
{
if(m & 1)
{
res = (res * n ) % mod;
}
n = n * n % mod ;
m >>= 1;
}
return res;
}
int main()
{
int a , b , n;
while(cin >> a >> b >> n)
{
Mat m;
m.mat[0][0] = 1;
m.mat[0][1] = 1;
m.mat[1][0] = 1;
m.mat[1][1] = 0;
if(n > 1)
{
m = m ^ (n - 1);
/* for(int i = 0; i < N; ++i)
{
for(int j = 0; j < N; ++j)
cout << m.mat[i][j] <<" ";
cout << endl;
}
*/
cout <<(Pow( b , m.mat[0][0] , MOD )% MOD * Pow( a , m.mat[1][0] , MOD ) )%MOD << endl;
}
else if(n == 0) cout << a << endl;
else cout << b << endl;
}
return 0 ;
}