链接:https://ac.nowcoder.com/acm/contest/10507/A
来源:牛客网
广义肥波那契数列,以递归的方法定义如下:
\begin{cases}f_1=1\f_2=1\f_n=a\cdot f_{n-1}+b\cdot f_{n-2}(n\ge 3, n\in \mathbb Z)\end{cases}
⎩
⎪
⎨
⎪
⎧
f
1
=1
f
2
=1
f
n
=a⋅f
n−1
+b⋅f
n−2
(n≥3,n∈Z)
例如,当a=b=\text 1a=b=1时,数列为[\text 1,1,2,3,5,8,13,…][1,1,2,3,5,8,13,…]。
现在,请求出。
输入描述:
输入共一行,包含\text 44个正整数a,b,m,n(1\le a,b,m\le 10^9,1\le n \le 10^5)a,b,m,n(1≤a,b,m≤10
9
,1≤n≤10
5
)。
输出描述:
输出共一行,包含一个非负整数表示答案。由于结果可能较大,你只需要输出答案对10^9+7=1,000,000,00710
9
+7=1,000,000,007取模的结果。
示例1
输入
复制
1 1 2 4
输出
复制
8
说明
公式:2的m次方对mod 取余数,可以先对mod-1取余数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2;
typedef unsigned long long LL;
LL n, m, a, b;
const LL mod = 1e9 + 7;
void mul(LL c[][N], LL a[][N], LL b[][N])
{
LL temp[N][N] = {0};
for (int i = 0; i < N; i ++ )
for (int j = 0; j < N; j ++ )
for (int k = 0; k < N; k ++ )
temp[i][j] = (temp[i][j] + (a[i][k]) * (b[k][j]) % (mod - 1)) % (mod - 1) ;
memcpy(c, temp, sizeof temp);
}
long long qmi(LL a, LL b, LL p){
long long res = 1 % p;
while(b){
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return (long long)res;
}
int main(){
cin >> a >> b >> m >> n;
LL f[2][2] = {{1, 1},
{0, 0}};
//scanf("%lld%lld%lld%lld", &a, &b, &m, &n);
LL s[2][2] = {
{0, b},
{1, a}
};
n --;
while(n){
if (n & 1){
mul(f, f, s);
// cout << f[0][0] << "---" <<endl;
}
mul(s, s, s);
n >>= 1;
}
LL fn = f[0][0] % (mod - 1);
//cout << fn << "-------" << endl;
long long ans = qmi(m, fn, mod) % mod ;
//cout << a << "-------" << b << "-------" << m << "-------"<< n << endl;
cout << ans << endl;
return 0;
}
这里需要注意n为1n为2的情况,所以初始化的时候需要注意
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL qmi(LL a, LL b, LL p){
LL res = 1 % p;
while(b){
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
int main(){
LL a, b, m, n;
cin >> a >> b >> m >> n;
LL x1 = 1, x2 = 1;
LL ans = 1;
for (int i =3; i <= n; i ++){
ans = (1ll * a * x2) % (mod - 1) + (1ll * b * x1) % (mod - 1) ;
ans %= (mod - 1);
x1 = x2;
x2 = ans;
}
LL fn = ans % (mod - 1);
cout << qmi(m, fn, mod) % mod << endl;
return 0;
}