• COJ 1208 矩阵快速幂DP


      题目大意:

    f(i) 是一个斐波那契数列 , 求sum(f(i)^k)的总和

    由于n极大,所以考虑矩阵快速幂加速

    我们要求解最后的sum[n]

    首先我们需要思考

    sum[n] = sum[n-1] + f(i+1)^k

    那么很显然sum[n-1]是矩阵中的一个元素块

    那么f(i+1)^k怎么利用f(i) , f(i-1)来求

    f(i+1)^k = (f(i) + f(i-1)) ^ k

    假如k = 1 , 可以看出f(i+1) = f(i-1) + f(i) (1,1)

          k = 2 , 可以看出f(i+1)^2 = f(i-1)^2 + 2*f(i-1)*f(i) + f(i)^2 (1 , 2 , 1)

    后面只列出前面的因子 k=3          1 , 3 , 3 , 1

              k =4          1, 4 ,6,4,1

            很容易看出后一行的数是由前一行的数当前列和前一列的相加

    那么这里要放入矩阵中思考的就是 f(i-1)^k , f(i-1)^(k-1)*f(i) ...... f(i)^k , sum[i] 这样 k+2 个元素

    那么做矩阵快速幂就是利用f(i-1)^k , f(i-1)^(k-1)*f(i) ...... f(i)^k , sum[i]  乘以某一个矩阵得到

    f(i)^k , f(i)^(k-1)*f(i+1) ...... f(i+1)^k , sum[i+1]

    自己一个个递推就会渐渐利用上述的关系轻松得到这个矩阵

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 using namespace std;
     5 #define N 100
     6 #define ll long long
     7 const int MOD = 1000000007;
     8 int n , k , l;
     9 int num[N];
    10 
    11 struct Matrix{
    12     int a[N][N];
    13     Matrix operator*(const Matrix &m) const{
    14         Matrix ans ;
    15         for(int i=0 ; i<l ; i++){
    16             for(int j=0 ; j<l ; j++){
    17                 ans.a[i][j] = 0;
    18                 for(int k=0 ; k<l ; k++){
    19                     ans.a[i][j] += ((ll)a[i][k] * m.a[k][j])%MOD;
    20                     ans.a[i][j] %= MOD;
    21                 }
    22             }
    23         }
    24         return ans;
    25     }
    26 }st;
    27 
    28 Matrix q_pow(Matrix b , int t)
    29 {
    30     Matrix ans;
    31     memset(ans.a , 0 , sizeof(ans));
    32     for(int i=0 ; i<l ; i++) ans.a[i][i] = 1;
    33     while(t)
    34     {
    35         if(t&1) ans = ans*b;
    36         b = b*b;
    37         t>>=1;
    38     }
    39     return ans;
    40 }
    41 
    42 void build_matrix()
    43 {
    44     memset(st.a , 0 , sizeof(st.a));
    45     st.a[l-2][0] = 1;
    46     for(int i=1 ; i<l-1 ; i++){
    47         for(int j=l-2 , t=0 ; t<=i ; t++,j--){
    48             st.a[j][i] = st.a[j][i-1]+st.a[j+1][i-1];
    49         }
    50     }
    51     for(int i=0 ; i<l-1 ; i++)
    52         st.a[i][l-1] = st.a[i][l-2];
    53     st.a[l-1][l-1] = 1;
    54 }
    55 
    56 int main()
    57 {
    58     #ifndef ONLINE_JUDGE
    59         freopen("a.in" , "r" , stdin);
    60     #endif // ONLINE_JUDGE
    61     int T;
    62     scanf("%d" , &T);
    63     while(T--)
    64     {
    65         scanf("%d%d" , &n , &k);
    66         l = k+2;
    67         build_matrix();
    68         for(int i=0 ; i<l-1 ; i++){
    69             num[i] = 1;
    70         }
    71         num[l-1] = 2;
    72         if(n<=2) printf("%d
    " , n);
    73         else{
    74             Matrix ans = q_pow(st , n-2);
    75             int ret = 0;
    76             for(int i=0 ; i<l ; i++){
    77                 ret += num[i]*ans.a[i][l-1]%MOD;
    78                 ret %= MOD;
    79             }
    80             printf("%d
    " , ret);
    81         }
    82     }
    83     return 0;
    84 }

     

  • 相关阅读:
    Get IPv4 Address 2.0
    Apache Tomcat Manager 2.0
    Apache Tomcat Manager 1.0
    FTP自动登录脚本文件
    VMware Workstation 10 + CentOS-5.5-i386 + MySQL Server 5.5
    Copy Files Blurry 1.0
    Extract Chorus From Audio 1.0
    Refresh Baidu Zhidao Evaluate Num 2.0
    File Split 1.0
    其它有趣的事情分享
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4537453.html
Copyright © 2020-2023  润新知