题目描述
本题测试样例已经更(jia)新(qiang)。
μ’s在九人齐心协力下,影响力越来越大了!
已知第一天影响力为
x
x
x ,第二天影响力为
y
y
y ,从第三天开始,每一天的影响力为前两天影响力的乘积再乘以
a
a
a 的
b
b
b 次方。 用数学语言描述是:
设第
i
i
i 天的影响力为
f
(
i
)
f(i)
f(i) ,那么
f
(
1
)
=
x
f(1)=x
f(1)=x ,
f
(
2
)
=
y
f(2)=y
f(2)=y,对于
i
>
2
i>2
i>2 ,
f
(
i
)
=
f
(
i
−
1
)
∗
f
(
i
−
2
)
∗
a
b
f(i)=f(i-1)*f(i-2)*a^b
f(i)=f(i−1)∗f(i−2)∗ab
她们想知道第
n
n
n 天影响力是多少?
由于这个数可能非常大,只需要输出其对
1000000007
1000000007
1000000007 取模的值就可以了。
输入描述:
一行五个正整数:
n
,
x
,
y
,
a
,
b
n,x,y,a,b
n,x,y,a,b 。
(
1
<
=
n
,
x
,
y
,
a
,
b
<
=
1
0
12
)
(1<=n,x,y,a,b<=10^{12})
(1<=n,x,y,a,b<=1012)
输出描述:
第 n n n 天的影响力对 1000000007 1000000007 1000000007 取模的值。
输入
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是素数。
题解
- 显然
f
(
n
)
f(n)
f(n) 可以用
x
x
x ,
y
y
y 和
a
a
a 这三个因子表达出来。
每一项a的幂次分别是 0 、 0 、 b 、 2 b 、 4 b 、 7 b 、 12 b … … 0、0、b、2b、4b、7b、12b…… 0、0、b、2b、4b、7b、12b…… 从第三项开始每一项为前两项之和加1。
而 x x x 和 y y y 的幂次构成斐波那契数列: x x x 的幂次第一项是 1 1 1 ,第二项是 0 0 0; y y y 的幂次第一项是 0 0 0,第二项是 1 1 1。之后每一项均为前两项之和。 - 根据费马小定理,由于 1 e 9 + 7 1e9+7 1e9+7 是素数,有 a 1 e 9 + 6 ≡ 1 ( m o d 1 e 9 + 7 ) {a\mathop{{}}\nolimits^{{1e9+6{\text{ }}}} \equiv 1 \left( mod\text{ }1e9+7 \right) } a1e9+6 ≡1(mod 1e9+7)。因此幂的指数对 1 e 9 + 6 1e9+6 1e9+6 取模即可。要注意a是1000000007的倍数的特殊情况。
- 可以用矩阵快速幂 O ( l o g n ) O(logn) O(logn) 求出 x 、 y 、 a x、y、a x、y、a 幂次的第 n n n 项。
- 参 考 c f 难 度 分 : 2200 参考cf难度分:2200 参考cf难度分:2200
特别注意(赛后加强数据)
- 注意
x
%
(
1
e
9
+
7
)
=
0
时
,
并
且
x
的
次
幂
也
为
0
时
,
正
确
答
案
应
该
是
0
,
但
是
由
于
q
_
p
o
w
(
0
,
0
)
返
回
的
是
1
,
会
导
致
答
案
非
0
。
所
以
要
防
止
幂
为
0
的
特
殊
情
况
。
x\%(1e9+7)=0时,并且x的次幂也为0时,正确答案应该是0,但是由于q\_pow(0,0)返回的是1,会导致答案非0。所以要防止幂为0的特殊情况。
x%(1e9+7)=0时,并且x的次幂也为0时,正确答案应该是0,但是由于q_pow(0,0)返回的是1,会导致答案非0。所以要防止幂为0的特殊情况。
提供数据:1000000010 1000000007 3 5 1 - 先 计 算 a 的 b 次 方 可 以 避 免 b 模 m o d − 1 为 0 的 情 况 先计算a的b次方可以避免b模mod-1为0的情况 先计算a的b次方可以避免b模mod−1为0的情况
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;
}
}
}