传送门

 

参考资料:

  [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

 1 #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 }
View Code

相关文章: