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

    题目链接:http://poj.org/problem?id=3233

    解题报告:输入一个边长为n的矩阵A,然后输入一个k,要你求A + A^2 + A^3 + A^4 + A^5.......A^k,然后结果的每个元素A[i][j] % m。(n <= 30,k < 10^9,m < 10^4)

    要用到矩阵快速幂,但我认为最重要的其实还是相加的那个过程,因为k的范围是10^9,一个一个加肯定是不行的,我想了一个办法就是我以k = 8为例说明:

    ans = A + A^2 + A^3 + A^4 + A^5 + A^6 + A^7 + A^8

    = A + A^2 + A^3 + A^4 + A^4 * (A + A^2 + A^3 + A^4)   // 这样分成两块之后就只要算一次A + A^2 + A^3 + A^4,就可以得出最后结果,

    而A + A^2 + A^3 + A^4这个又可以通过相同的方法划分成如下:

    = A + A^2 + A^2 * (A + A^2)同理。。。。就可以在logn时间求出他们的和了,然后快速的求A^k次方是用二分矩阵快速幂这里就不说了。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<deque>
      6 #include<cmath>
      7 using namespace std;
      8 typedef __int64 INT;
      9 const int N = 31;
     10 int m;
     11 
     12 struct node
     13 {
     14     INT t[N][N];
     15     int n;
     16     friend node operator * (node a,node b)
     17     {
     18         node B = a;
     19         for(int i = 0;i < a.n;++i)
     20         for(int j = 0;j < a.n;++j)
     21         {
     22             int tot = 0;
     23             for(int k = 0;k < a.n;++k)
     24             tot += ((a.t[i][k] * b.t[k][j]) % m);
     25             B.t[i][j] = tot % m;
     26         }
     27         return B;
     28     }
     29     friend node operator + (node a,node b)
     30     {
     31         node B;
     32         B.n = a.n;
     33         for(int i = 0;i < a.n;++i)
     34         for(int j = 0;j < a.n;++j)
     35         B.t[i][j] = (a.t[i][j] + b.t[i][j]) % m;
     36         return B;
     37     }
     38 };
     39 node A;
     40 void print(node t)
     41 {
     42     for(int i = 0;i < t.n;++i)
     43     for(int j = 0;j < t.n;++j)
     44     printf(j == t.n-1? "%d
    ":"%d ",t.t[i][j]);
     45 }
     46 node Pw(node tt,int n)   //二分矩阵快速幂求A ^ n 
     47 {
     48     if(n == 1) return A;
     49     node res;
     50     res.n = tt.n;
     51     memset(res.t,0,sizeof(res.t));
     52     for(int i = 0;i < res.n;++i)
     53     res.t[i][i] = 1;
     54     while(n)
     55     {
     56         if(n & 1)
     57         res = res * tt;
     58         n >>= 1;
     59         tt = tt * tt;
     60     }
     61     return res;
     62 }    
     63 
     64 node get_ans(int n)    //求A^1 到 A ^ n的和 
     65 {
     66     if(n == 1)
     67     return A;
     68     if(n & 1)
     69     {
     70         node temp1;
     71         temp1.n = A.n;
     72         temp1 = Pw(A,n);
     73         node temp2;
     74         temp2.n = 2;
     75         temp2 = get_ans(n-1);
     76         temp1 = temp1 + temp2;
     77         return temp1;
     78     }
     79     else
     80     {
     81         node temp1;
     82         temp1.n = A.n;
     83         temp1  = Pw(A,n / 2);
     84         node temp2 = get_ans(n / 2);
     85         temp2.n = A.n;
     86         temp1 = temp1 * temp2;
     87         temp1 = temp1 + temp2;
     88         return temp1;
     89     }
     90 }
     91 
     92 int main()
     93 {
     94     
     95     int n,k;
     96     while(scanf("%d%d%d",&n,&k,&m)!=EOF)
     97     {
     98         A.n = n;
     99         for(int i = 0;i < n;++i)
    100         for(int j = 0;j < n;++j)
    101         scanf("%d",&A.t[i][j]);
    102         node ans = get_ans(k);
    103         print(ans);
    104     }
    105     return 0;
    106 } 
    View Code
  • 相关阅读:
    webapi帮助文档swagger
    后台任务hangfire
    EF6 DbModelBuilder
    .net跨平台分析软件
    EF迁移命令
    NuGet Package Explorer
    ghost blog 中文资料
    IDependency自动注册autofac
    Abp zero 示例运行
    AutoMapperExtension
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3881539.html
Copyright © 2011-2022 走看看