zoukankan      html  css  js  c++  java
  • 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
    没有梦想,何谈远方
  • 相关阅读:
    hdu4990矩阵快速幂
    预处理+状态压缩+剪枝——codefoece 1209E
    AC自动机处理多串匹配——cf1202E
    二维差分前缀和——cf1202D(好题)
    序列递推——cf1204E(好题)
    建模+线性dp——cf1201D
    暴力——cf1202C
    经典排序背包——cf1203F
    思维+贪心——cf1042D
    分块——cf1207F
  • 原文地址:https://www.cnblogs.com/zyue/p/3977175.html
Copyright © 2011-2022 走看看