zoukankan      html  css  js  c++  java
  • POJ 3233 Matrix Power Series 矩阵快速幂 + 二分

    题意:求矩阵的次方和

    解题思路:最容易想到方法就是两次二分因为 我们可以把一段  A^1 + A^2 + .......A^K   变成  A^1 + ..A^(K/2) +( A^1 + ..A^(K/2))*(A^(k/2)) 当k 为奇数的时候 或者 A^1 + ..A^(K/2) +( A^1 + ..A^(K/2))*(A^(k/2)) + A^K 当K 为偶数的时候。

    解题代码:

      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 using namespace std;
     26 int  n ,m , k ; 
     27 int  ta,tb;
     28 struct Matrix
     29 {
     30    int   mat[30][30];
     31    void clear()
     32    {
     33       memset(mat,0,sizeof(mat));
     34    }
     35    void output()
     36    {
     37      for(int i =0  ;i < n ;i ++)
     38      {
     39        for(int j = 0 ;j < n ;j ++)
     40            printf("%d ",mat[i][j]);
     41      printf("
    ");
     42      }
     43    }
     44    void init()
     45    {
     46       clear();
     47       for(int i = 0 ;i < n;i ++)
     48           for(int j = 0 ;j < n;j ++)
     49           {
     50             scanf("%d",&mat[i][j]);
     51           }
     52    }
     53    Matrix operator *(const Matrix &b) const
     54    {
     55        Matrix ret;
     56        ret.clear();
     57        for(int i = 0 ;i < n ;i ++)
     58            for(int j = 0;j < n;j ++)
     59            {
     60                for(int s = 0 ;s < n ;s ++)
     61                {
     62                  ret.mat[i][j] =(ret.mat[i][j] + mat[i][s] * b.mat[s][j]) % m ; // 第I 行  第J  列        
     63                }
     64            }
     65        return ret;
     66    }
     67    Matrix operator *(const int  &b) const
     68    {
     69        Matrix ret;
     70        ret.clear();
     71        for(int i = 0 ;i < n ;i ++)
     72            for(int j = 0;j < n;j ++)
     73            {
     74                 ret.mat[i][j] = (mat[i][j] * b) % m ; // 第I 行  第J  列        
     75            }
     76        return ret;
     77    }
     78    Matrix operator +(const Matrix &b) const
     79    {
     80        Matrix ret;
     81        ret.clear();
     82        for(int i = 0 ;i < n ;i ++)
     83            for(int j = 0;j < n;j ++)
     84            {
     85                 ret.mat[i][j] = (mat[i][j] + b.mat[i][j]) % m ; // 第I 行  第J  列        
     86            }
     87        return ret;
     88    }
     89 };
     90 Matrix Pow( Matrix a ,LL t )
     91 {
     92   Matrix ret;
     93   ret.clear();
     94   for(int i = 0 ;i < n ;i ++)
     95        ret.mat[i][i] = 1;
     96   Matrix tmp = a; 
     97   while(t)
     98   {
     99       if(t&1) ret = ret * tmp;
    100       tmp = tmp * tmp;
    101       t >>=1;
    102   }
    103   return ret;
    104 }
    105 Matrix add(Matrix a, int k )
    106 {
    107     Matrix ans;
    108     ans.clear();
    109     if(k == 1)
    110     {
    111       return a;
    112     }
    113     if(k&1)
    114     {
    115           Matrix temp = add(a,k/2);
    116           ans = temp + temp * Pow(a,k/2) + Pow(a,k);
    117     }else{
    118           Matrix temp = add(a,k/2);
    119           ans = temp + temp * Pow(a,k/2);
    120     }
    121     return ans ; 
    122 }
    123 int main(){
    124     LL l ;
    125     while(scanf("%d %d %d",&n,&k,&m) != EOF)
    126     {
    127         Matrix  a;
    128         a.clear();
    129         a.init();
    130         a = add(a,k);
    131         //a.output();
    132         a.output();
    133     }
    134     return 0;
    135 }
    View Code

    写完以后过了竟然跑了 1300+ms  最快 0ms  不能忍上网查题解 发现了这种方法 :http://www.cnblogs.com/rainydays/archive/2011/02/21/1960189.html

    他的主要思想是多加 n维度 构成一个能累加的矩阵 ,具体看博主题解。

    这种思想很巧妙。

    没有梦想,何谈远方
  • 相关阅读:
    java8 .stream().map().collect()
    函数式编程扫盲篇(转载)
    如何成为Python高手(转载)
    JAVA通过XPath解析XML性能比较(原创)
    不要过早退出循环 while(1){no break}
    搭建harbor私有仓库
    Supervisor进程管理
    一键部署redis-5.0.5
    Linux下的crontab定时执行任务命令详解
    利用shell脚本实现对mysql数据库的备份
  • 原文地址:https://www.cnblogs.com/zyue/p/3979014.html
Copyright © 2011-2022 走看看