https://ac.nowcoder.com/acm/problem/200658
f(n) = f(n-1) * f(n-2) * ab ,f的第一项是x,第二项是y。
试着推出第三项是x·y·ab,第四项是x·y2·a2b,第五项是x2·y3·a4b,第六项是x3y5a7b
可以发现x的指数成1 0 1 1 2 3,y的指数0 1 1 2 3 5,a的指数是0 0 b 2b 4b 7b。
x和y的指数为斐波那契数列,a的指数规律为,除去系数b,其第n项前两项之和+1。
由于数据范围很大,所以可以用矩阵快速幂求出x y a的指数的第n项是多少。
x和y的乘法矩阵比较好构造
1 1
1 0
对于b的乘法矩阵,因为f(n)= f(n-1)+ f(n-2)+ 1
所以可以构造为:
1 1 1
1 0 0
0 0 1
因为最终是要求x·y·a的某次幂,且mod = 1e9+7是一个素数,所以这里再矩阵快速幂求解的过程中用费马小定理进行降幂操作
因为ap-1≡1%p,所以ab%p = ab%(p-1)%p,在矩阵快速幂计算过程中矩阵元素相乘对mod-1取模而不是mod
求出指数后,再用快速幂求解即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll mod = 1e9+7; 5 struct Matrix { 6 ll a[3][3]; 7 Matrix() { memset(a, 0, sizeof a); } 8 Matrix operator*(const Matrix &b) const {//重载矩阵乘法 9 Matrix res; 10 for (int i = 0; i <= 2; ++i) 11 for (int j = 0; j <= 2; ++j) 12 for (int k = 0; k <= 2; ++k) 13 res.a[i][j] = (res.a[i][j] + (a[i][k] * b.a[k][j] )%(mod-1) ) % (mod-1); 14 return res; 15 } 16 }base1,base2,B,X,Y; 17 18 void init(){ 19 base1.a[0][0] = base1.a[0][1] = base1.a[1][0] = 1; 20 base2.a[0][0] = base2.a[0][1] = base2.a[0][2] = base2.a[1][0] = base2.a[2][2] = 1; 21 B.a[2][0] = X.a[1][0] = Y.a[0][0] = 1; 22 } 23 Matrix qpow(Matrix a,ll n) { 24 Matrix res; 25 res.a[0][0] = res.a[1][1] = res.a[2][2] = 1; 26 while (n) { 27 if (n & 1) res = res * a; 28 a = a * a; 29 n >>= 1; 30 } 31 return res; 32 } 33 ll power(ll a,ll n){ 34 ll res=1; 35 a = a % mod; 36 while(n){ 37 if(n&1)res=res*a%mod; 38 n>>=1; 39 a=a*a% mod; 40 } 41 return res; 42 } 43 44 int main(){ 45 ll n,x,y,a,b; 46 cin>>n>>x>>y>>a>>b; 47 if(n == 1) { 48 cout<<x%mod; 49 return 0; 50 } 51 if(n == 2){ 52 cout<<y%mod; 53 return 0; 54 } 55 if(x%mod==0||y%mod==0||a%mod==0){cout<<0;return 0;} 56 x%=mod,y%=mod; 57 init(); 58 Matrix b1 = qpow(base1,n-2); 59 Matrix b2 = qpow(base2,n-2); 60 X = b1*X,Y = b1*Y,B = b2*B; 61 ll Cx = X.a[0][0],Cy = Y.a[0][0],Cb = B.a[0][0]; 62 a = power(a%mod,b); 63 ll ans = ((power(x,Cx)*power(y,Cy)%mod)*power(a,Cb)%mod); 64 cout<<ans; 65 return 0; 66 }