很多人看不到题目呀,那我拍一下。
实际上,这道题我们很容易推出它的矩阵快速幂形式。
其实就是x、y、分别的幂了。
然后,就是维护对应的幂了,这时候,我们需要考虑特殊情况。
也就是在这里“”这是一个很重要的性质!因为作为底数的0,实际上是被取模之后的0,而上面的作为指数的0,一定是不真正为0的,所以他们的幂次数一定是为0的!而我们正常的快速幂都是无法判断的,所以,最后我们需要加上一组特判!可以选择像我一样加在快速幂的函数内部。
当然,还有个细节就是我们处理矩阵快速幂的时候,取的模可是欧拉(mod),也就是mod - 1。这是费马小定理的原理。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const ll mod = 1e9 + 7LL, P = 1e9 + 6LL;
inline ll fast_mi(ll a, ll b, ll M)
{
ll ans = 1;
while(b)
{
if(b & 1LL) ans = ans * a % M;
a = a * a % M;
b >>= 1LL;
}
if(!a) ans = 0; //这里特殊,因为存在0的0次幂,而第二个所谓的“0次幂”是假的0,其实是有真实值的
return ans;
}
struct matrice
{
ll a[3][3];
matrice() { memset(a, 0, sizeof(a)); }
friend matrice operator * (matrice x, matrice y) //重载函数,矩阵的乘积得到的新矩阵
{
matrice ans;
for(int i=0; i<2; i++)
{
for(int j=0; j<2; j++)
{
ll tmp = 0;
for(int k=0; k<2; k++)
{
tmp = (tmp + x.a[i][k] * y.a[k][j] % P) % P; //最后得到的需要取mod
}
ans.a[i][j] = tmp;
}
}
return ans;
}
}Bas, AI, M1, M2, Bg, G;
matrice Fast_Mi(matrice x, ll ti)
{
matrice ans;
for(int i=0; i<3; i++) ans.a[i][i] = 1; //构造单位阵
while(ti)
{
if(ti & 1LL) ans = ans * x;
x = x * x;
ti >>= 1LL;
}
return ans;
}
ll N, x, y, a, b, K;
inline void init()
{
Bas = matrice();
Bas.a[0][0] = 1; Bas.a[0][1] = 1;
Bas.a[1][0] = 1; Bas.a[1][1] = 0;
AI = matrice();
AI.a[0][0] = 1;
AI.a[1][0] = 1;
}
int main()
{
scanf("%lld%lld%lld%lld%lld", &N, &x, &y, &a, &b);
a %= mod; x %= mod; y %= mod;
b %= P;
K = fast_mi(a, b, mod);
if(N <= 3)
{
if(N == 1) printf("%lld\n", x % mod);
else if(N == 2) printf("%lld\n", y % mod);
else printf("%lld\n", x * y % mod * K % mod);
return 0;
}
init();
M1 = Fast_Mi(Bas, N - 3LL); M2 = Fast_Mi(Bas, N - 4LL);
M1 = M1 * AI; M2 = M2 * AI;
G = Fast_Mi(Bas, N - 1LL);
printf("%lld\n", fast_mi(y, M1.a[0][0], mod) * fast_mi(x, M2.a[0][0], mod) % mod * fast_mi(a, b * (G.a[0][0] - 1LL + P) % P, mod) % mod);
return 0;
}
/*
5 2 3 2 1
ans:1728
*/