我昨天写这个题,写道凌晨两点,一直81分,直到刚才,我发现了错误的地方,一改就A了,woc,心态崩了
μ’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 , f ( i ) = f ( i − 1 ) ∗ f ( i − 2 ) ∗ a b i>2,f(i)=f(i-1)*f(i-2)*a^b i>2,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\leq n,x,y,a,b\leq 10^{12}) (1≤n,x,y,a,b≤1012)
输出:第 n n n天的影响力对 1000000007 1000000007 1000000007 取模的值。
x x x 和 y y y 的幂次是叠加的,因为是幂的乘积嘛,而且是 f ( i ) = f ( i − 1 ) ∗ f ( i − 2 ) f(i)=f(i-1)*f(i-2) f(i)=f(i−1)∗f(i−2),可以发现,指数其实就是 g ( i ) = g ( i − 1 ) + g ( i − 2 ) g(i)=g(i-1)+g(i-2) g(i)=g(i−1)+g(i−2),其实就是Fib了,求斐波那契数列, x x x 和 y y y 指数就得到了解决。而对于 a a a 的指数,可以明了 b b b 是不变的,所以只有 b b b 前面的系数在变化,而 b b b 前面的系数是当前项 x x x 和 y y y 的系数之和 − 1 -1 −1,因此 b b b 的系数也得到了解决。
因为数据量很大,所以不能通过递推求Fib,可以通过矩阵快速幂求解Fib,但是Fib很大,需要取模,而Fib又在指数位置上,根据费马小定理(或者欧拉降幂公式),让Fib对( 1 0 9 + 7 − 1 10^9+7-1 109+7−1)取模即可。
注意: n = 1 ∣ ∣ n = 2 n=1||n=2 n=1∣∣n=2的时候直接输出 x ∣ ∣ y x||y x∣∣y但是,因为 x ∣ ∣ y x||y x∣∣y的值都很大,答案需要对 1 0 9 + 7 10^9 +7 109+7取模。(我就这个地方wa了好多好多遍)
#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof a)
const int mod = 1e9 + 7;
typedef long long ll;
ll qc(ll x,ll y,ll m)
{
return (x*y-(ll)((long double)x/m*y)*m+m)%m;
}
ll qpow(ll x, ll y, ll m){
ll res = 1;
res %= m;
while (y){
if(y & 1){
res = qc(res, x, m);
}
y >>= 1;
x = qc(x, x, m);
}
return res % m;
}
struct p{
ll a[3][3];
p(){
mem(a, 0);
}
void clear(){
p();
}
p(ll b[3][3]){
clear();
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a[i][j] = b[i][j];
}
p operator * (const p& temp){
p ans;
ans.clear();
for (int i = 1; i <= 2; i++){
for (int j = 1; j <= 2; j++){
for (int k = 1; k <= 2; k++){
ans.a[i][j] += qc(this->a[i][k], temp.a[k][j], mod - 1);
ans.a[i][j] %= (mod - 1);
}
}
}
return ans;
}
};
p qpow(p t, ll n){
p res;
res.clear();
res.a[1][1] = 1;
res.a[2][2] = 1;
while (n){
if (n & 1){
res = res * t;
}
n >>= 1;
t = t * t;
}
return res;
}
ll n, x, y, a, b;
int main()
{
while(~scanf("%lld %lld %lld %lld %lld", &n, &x, &y, &a, &b)){
ll fib1, fib2;
p temp;
temp.clear();
temp.a[1][2] = temp.a[2][1] = temp.a[2][2] = 1;
if (n == 1){
printf("%lld\n", x % mod);
}
else if (n == 2){
printf("%lld\n", y % mod);
}
else {
p ans = qpow(temp, n - 2);
fib1 = ans.a[2][1];
fib2 = ans.a[2][2];
ll z = fib1 + fib2 - 1;
ll res = qpow(x, fib1 % (mod - 1), mod);
res = qc(res, qpow(y, fib2 % (mod - 1), mod), mod);
a = qpow(a, b, mod);
res = qc(res, qpow(a, z, mod), mod);
res %= mod;
if (x % mod == 0 || y % mod == 0 || a % mod == 0){
res = 0;
}
printf("%lld\n", res);
}
}
return 0;
}