广义肥波
题目链接:nowcoder 214267
到牛客看:
题目大意
定义广义斐波那契数列:
{
f
1
=
1
f
2
=
1
f
i
=
a
×
f
i
−
1
+
b
×
f
i
−
2
(
n
≥
3
,
n
∈
Z
)
\left\{\begin{matrix} f_1=1\\ f_2=1\\ f_i=a\times f_{i-1}+b\times f_{i-2}(n\geq3,n\in \mathbb{Z}) \end{matrix}\right.
⎩⎨⎧f1=1f2=1fi=a×fi−1+b×fi−2(n≥3,n∈Z)
然后让你求
m
f
n
%
(
1
e
9
+
7
)
m^{f_n} \%(1e9+7)
mfn%(1e9+7)
思路
看到题目的范围,我们可以看出应该是枚举一个 n n n,然后其他数的 log,大概这样的复杂度。
然后很明显枚举 n n n 可以得出 f n f_n fn,但是你要求的是 m f n m^{f_n} mfn, f n f_n fn 不能取模,你总不能搞高精吧。
那我们考虑不求
f
n
f_n
fn,枚举
n
n
n 求出
m
f
i
m^{f_i}
mfi 的值
g
i
g_i
gi。
那我们可以看出转移就是:
g
i
=
g
i
−
1
a
×
g
i
−
2
b
g_i=g_{i-1}^a\times g_{i-2}^b
gi=gi−1a×gi−2b。(就是全部运算往上诺一级)
这样就可以在取模的意义下进行而不出问题了。
代码
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define mo 1000000007
using namespace std;
ll a, b, m, re, tmp, l, r;
int n;
ll ksm(ll x, ll y) {
re = 1ll;
while (y) {
if (y & 1) re = (re * x) % mo;
x = (x * x) % mo;
y >>= 1;
}
return re;
}
int main() {
scanf("%lld %lld %lld %d", &a, &b, &m, &n);
l = r = m;
for (int i = 3; i <= n; i++) {
tmp = (ksm(l, b) % mo * ksm(r, a)) % mo;
l = r;
r = tmp;
}
printf("%lld", r);
return 0;
}