其他分享
首页 > 其他分享> > 牛客竞赛 缪斯的影响力 (矩阵快速幂/费马小定理降幂)

牛客竞赛 缪斯的影响力 (矩阵快速幂/费马小定理降幂)

作者:互联网

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 }

 

标签:const,Matrix,降幂,res,ll,矩阵,牛客,缪斯,mod
来源: https://www.cnblogs.com/AaronChang/p/12266263.html