题目描述
本题测试样例已经更(jia)新(qiang)。
μ’s在九人齐心协力下,影响力越来越大了!
已知第一天影响力为
,第二天影响力为
,从第三天开始,每一天的影响力为前两天影响力的乘积再乘以
的
次方。 用数学语言描述是:
设第
天的影响力为
,那么
,
,对于
,
她们想知道第
天影响力是多少?
由于这个数可能非常大,只需要输出其对
取模的值就可以了。
输入描述:
一行五个正整数:
。
输出描述:
第 天的影响力对 取模的值。
输入
4 2 3 2 1
输出
72
说明
f(1)=2,f(2)=3,f(3)=f(1)*f(2)*2=12,f(4)=f(2)*f(3)*2=72
备注:
1000000007是素数。
题解
- 显然
可以用
,
和
这三个因子表达出来。
每一项a的幂次分别是 从第三项开始每一项为前两项之和加1。
而 和 的幂次构成斐波那契数列: 的幂次第一项是 ,第二项是 ; 的幂次第一项是 ,第二项是 。之后每一项均为前两项之和。 - 根据费马小定理,由于 是素数,有 。因此幂的指数对 取模即可。要注意a是1000000007的倍数的特殊情况。
- 可以用矩阵快速幂 求出 幂次的第 项。
特别注意(赛后加强数据)
- 注意
提供数据:1000000010 1000000007 3 5 1
AC-Code
#include <bits/stdc++.h>
//#pragma GCC optimize("O3")
//#pragma G++ optimize("O3")
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
#define ll long long
#define RI register int
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int maxn = 3;
const int mod = 1e9 + 7;
struct mat {
int m[maxn][maxn];
mat() {
memset(m, 0, sizeof m);
}
}unit;
mat operator * (mat a, mat b) {
mat ret;
ll x;
for (ll i = 0; i < maxn; ++i)
for (ll j = 0; j < maxn; ++j) {
x = 0;
for (ll k = 0; k < maxn; ++k)
x += ((ll)a.m[i][k] * b.m[k][j]) % (mod - 1);
ret.m[i][j] = x % (mod - 1);
}
return ret;
}
void init_unit() {
for (int i = 0; i < maxn; ++i)
unit.m[i][i] = 1;
}
mat pow_mat(mat a, ll n) {
mat ret = unit;
while (n) {
if (n & 1) ret = ret * a;
a = a * a;
n >>= 1;
}
return ret;
}
ll q_mult(ll a, ll b, ll k) {
ll res = 0;
while (b) {
if (b & 1) res = (res + a) % k;
a = (a + a) % k;
b >>= 1;
}
return res;
}
ll q_pow(ll a, ll n, ll k) {
ll res = 1;
while (n) {
if (n & 1) res = q_mult(res, a, k);
a = (a * a) % k;
n >>= 1;
}
return res;
}
int main() {
ios;
init_unit();
ll n, x, y, a, b;
while (cin >> n >> x >> y >> a >> b) {
a = q_pow(a % mod, b, mod);
x = x % mod;
y = y % mod;
if (n == 1) {
cout << x << endl;
}
else if (n == 2) {
cout << y << endl;
}
else if (n == 3) {
cout << q_mult(q_mult(x, y, mod), a % mod, mod) << endl;
}
else {
mat mat_a, mat_b;
mat_b.m[0][0] = 1, mat_b.m[0][1] = 1, mat_b.m[0][2] = 0;
mat_b.m[1][0] = 1, mat_b.m[1][1] = 0, mat_b.m[1][2] = 1;
mat_b.m[2][0] = 0, mat_b.m[2][1] = 0, mat_b.m[2][2] = 0;
mat_a.m[0][0] = 1, mat_a.m[0][1] = 1, mat_a.m[0][2] = 0;
ll z1 = (mat_a * pow_mat(mat_b, n - 4)).m[0][0];
ll z2 = (mat_a * pow_mat(mat_b, n - 3)).m[0][0];
ll z3 = (mat_a * pow_mat(mat_b, n - 2)).m[0][0] - 1LL;
cout << q_mult(q_mult(q_pow(x, z1+mod-1, mod), q_pow(y, z2, mod), mod), q_pow(a % mod, z3 % (mod - 1), mod), mod) << endl;
}
}
}