【链接】
http://acm.hdu.edu.cn/showproblem.php?pid=4549
【题意】
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
给出a, b, n,求出F[n]
【分析】
写出几项后,发现:F[n]=a^x*b^y,x,y成斐波那契数列。
且有规律:ans=a^(F[n-1])*b^(F[n])
斐波那契数列F[]数组可通过矩阵快速幂n^3logk求解,但是由于n很大,继续直接求解会超时。
由费马小定理a^(p-1)+1==0(mod p).继续求解时可以简化幂上(p-1)得循环节。
【代码】
#include<bits./stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1000006;
const int mod = 1e9 + 7;
ll F[maxn];
ll a, b, n;
ll qpow2(ll a, ll b) {
ll res = 1;
ll ans = a % (mod);
while (b) {
if (b & 1)
res = res * ans%(mod);
ans = ans * ans%(mod);
b >>= 1;
}
return res;
}
struct ma {
ll m[2][2];
};
ma mul(ma a, ma b) {
ma c;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
c.m[i][j] = 0;
for (int k = 0; k < 2; k++) {
c.m[i][j] += (a.m[i][k] * b.m[k][j]) % (mod-1);
}
c.m[i][j] %= (mod-1);
}
}
return c;
}
ma qpow1(ma a, ll n) {
ma ans = { 1,0,0,1 };
ma res = a;
while (n) {
if (n & 1)ans = mul(ans, res);
res = mul(res, res);
n >>= 1;
}
return ans;
}
int main() {
ma tmp = { 0,1,1,1 };
while (~scanf("%lld%lld%lld", &a, &b, &n)) {
ma p = qpow1(tmp, n);
printf("%lld\n", qpow2(a, p.m[0][0])*qpow2(b, p.m[0][1]) % mod);
}
}