• HDU 1757 A Simple Math Problem 矩阵快速幂


    题意:给你一个序列,0 - 9 项已经知道了分别等于 下标 , 现在给你一个公式  f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);   

     要你求 f[m] % k, 其中m < 2^31。

    解题思路:矩阵快速幂。转移矩阵如下图。其实利用矩阵快速幂的重点和难点就是构造出转移矩阵

    盗图,google图片没有找到来源。

    这个图的意思是  把 F[9] 变为 F[10] ,然后把1-8都往下移位,消除 F0  ,进行 n-9次左乘 这个转置矩阵以后,就可以得出我们想要的解了,又因为有结合律,我们可以先对这个转移矩阵快速幂以后再求解。

    解题代码:

    快速幂的代码是参考了kuangbin的部分代码。

      1 // File Name: temp.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年09月17日 星期三 11时35分45秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #define LL long long
     25 
     26 using namespace std;
     27 int k , m; 
     28 struct Matrix
     29 {
     30    LL mat[10][10];
     31    void clear()
     32    {
     33       memset(mat,0,sizeof(mat));
     34    }
     35    void output()
     36    {
     37      for(int i =0  ;i < 10 ;i ++)
     38      {
     39        for(int j = 0 ;j < 10 ;j ++)
     40            printf("%I64d ",mat[i][j]);
     41      printf("
    ");
     42      }
     43    }
     44    void init()
     45    {
     46       for(int i = 0;i < 10 ;i ++) 
     47           for(int j = 0 ;j < 10;j ++)
     48           {
     49               if(i == j + 1 ) mat[i][j] = 1;
     50           }
     51    }
     52    Matrix operator *(const Matrix &b) const
     53    {
     54        Matrix ret;
     55        ret.clear();
     56        for(int i = 0 ;i < 10 ;i ++)
     57            for(int j = 0;j < 10;j ++)
     58            {
     59                for(int k = 0 ;k < 10 ;k ++)
     60                {
     61                  ret.mat[i][j] =(ret.mat[i][j] + mat[i][k] * b.mat[k][j]) % m ; // 第I 行  第J  列        
     62                }
     63            }
     64        return ret;
     65    }
     66 };
     67 Matrix Pow( Matrix a, int n)
     68 {
     69   Matrix ret;
     70   ret.clear();
     71   for(int i = 0 ;i <= 9 ;i ++)
     72        ret.mat[i][i] = 1;
     73   Matrix tmp = a; 
     74   while(n)
     75   {
     76       if(n&1) ret = ret * tmp;
     77       tmp = tmp * tmp;
     78       n >>=1;
     79   }
     80   return ret;
     81 }
     82 int main(){
     83     while(scanf("%d %d",&k,&m) != EOF)
     84     {
     85          Matrix  a;
     86          a.clear();
     87          for(int i =0 ;i < 10 ;i ++)
     88          {
     89              scanf("%I64d",&a.mat[0][i]);
     90          }
     91          a.init();
     92          //a.output();
     93          if(k <= 9 )
     94          {
     95             printf("%d
    ",k % m );
     96             continue;
     97          }
     98          a = Pow(a,k-9);
     99          //a.output();
    100          LL ans = 0 ;
    101          for(int i = 0 ;i <= 9;i ++)
    102          {
    103             ans =(ans + (9-i) * a.mat[0][i]) % m ;
    104          }
    105       printf("%I64d
    ",ans);
    106     }
    107 return 0;
    108 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    topcoder srm 681 div1
    topcoder srm 683 div1
    topcoder srm 684 div1
    topcoder srm 715 div1
    topcoder srm 685 div1
    topcoder srm 687 div1
    topcoder srm 688 div1
    topcoder srm 689 div1
    topcoder srm 686 div1
    topcoder srm 690 div1 -3
  • 原文地址:https://www.cnblogs.com/zyue/p/3977175.html
Copyright © 2020-2023  润新知