参考资料:
[1]:官方题解(提取码:ppi6)
B.generator 1(矩阵快速幂)
•题意
已知 $f_{i}=af_{i-1}+bf_{i-2}$;
输入 f0,f1,a,b,n,mod;
求 fn%mod ;
•题解
矩阵快速幂入门习题;
首先将递推式转化为矩阵乘法表达式:
$\left( \begin{array}{cc} f_{i} \\ f_{i-1} \end{array}\right)=\left( \begin{array}{cc} a&b \\ 1&0 \end{array}\right)\cdot\left( \begin{array}{cc} f_{i-1} \\ f_{i-2} \end{array}\right)$
不妨令 $\mathbf{A_{i}} =\left( \begin{array}{cc} f_{i} \\ f_{i-1} \end{array}\right)$ , $\mathbf{T} =\left( \begin{array}{cc} a&b \\ 1&0 \end{array}\right)$;
那么,原式可化为 $A_{i}=T\cdot A_{i-1}=T^{2}\cdot A_{i-2}= \cdots = T^{i-1}\cdot A_{1}$;
处理完递推式后,是不是就大功告成了?
no,no,no;
还差最后一步,如何处理 $T^{n-1}$ ?
n 很大很大很大;
考虑到秦九韶算法,将 n 分解;
假设 n-1 = 3194;
那么 n 可分解为 $n=\bigg(\Big(\big((3\times 10)+1\big)\times 10+9\Big)\times 10+4\bigg)$;
在计算 $T^{3194}$ 时,可以按照字符串的位数进行处理;
先计算 ans = T3;
ans = ans10·T1;(ans=T31)
ans = ans10·T9;(ans = T319)
ans = ans10·T4;(ans = T3194)
•Code
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem(a,b) memset(a,b,sizeof(a)) 4 #define ll long long 5 const int N=5; 6 const int maxn=1e6+50; 7 8 int f[2]; 9 int a,b,mod; 10 char s[maxn]; 11 struct Matrix 12 { 13 ll A[N][N]; 14 15 Matrix() 16 { 17 mem(A,0); 18 } 19 void Init() 20 { 21 for(int i=0;i < N;++i) 22 A[i][i]=1;///构造单位阵 23 } 24 }t,ans; 25 26 Matrix mult(Matrix a,Matrix b)///a*b 27 { 28 Matrix tmp; 29 for(int i=1;i <= 2;++i) 30 for(int j=1;j <= 2;++j) 31 for(int k=1;k <= 2;++k) 32 { 33 tmp.A[i][j] += a.A[i][k]*b.A[k][j]%mod; 34 tmp.A[i][j] %= mod; 35 } 36 return tmp; 37 } 38 Matrix qPow(Matrix a,int b)///a^b 39 { 40 Matrix tmp; 41 tmp.Init(); 42 43 while(b) 44 { 45 if(b&1) 46 tmp=mult(tmp,a); 47 a=mult(a,a); 48 b >>= 1; 49 } 50 return tmp; 51 } 52 int Solve() 53 { 54 ans.Init(); 55 t.A[1][1]=a; 56 t.A[1][2]=b; 57 t.A[2][1]=1; 58 59 int len=strlen(s+1); 60 for(int i=len;;--i) 61 { 62 if(s[i] != '0') 63 { 64 s[i]--; 65 for(int j=i+1;j <= len;++j) 66 s[j]='9'; 67 break; 68 } 69 } 70 71 for(int i=1;i <= len;++i) 72 { 73 ans=qPow(ans,10);///ans^10 74 ans=mult(ans,qPow(t,s[i]-'0'));///ans*t^(s[i]-'0') 75 } 76 return (ans.A[1][1]*f[1]%mod+ans.A[1][2]*f[0]%mod)%mod; 77 } 78 int main() 79 { 80 scanf("%d%d",f+0,f+1); 81 scanf("%d%d",&a,&b); 82 scanf("%s",s+1); 83 scanf("%d",&mod); 84 85 printf("%d\n",Solve()); 86 87 return 0; 88 }