zoukankan      html  css  js  c++  java
  • hdu 4965 Fast Matrix Calculation 快速矩阵幂

    【题意】一个矩阵N*K的矩阵A,一个K*N的矩阵B,(4 <= N <= 1000,2 <=K <= 6)。先进行矩阵乘法C=A*B,然后进行D=C^(N*N)的幂运算,然后

                对D的每个数对6取模,最后求出D的所有位置数字之和。

    【解法】   直接按照题目上的做 A*B 形成一个N*N的矩阵C,再用C求其n*n次幂。这样果断超时啊。

                   看了题解(AB)^n 可以写成 A (BA)^(n-1) B ,  B*A 形成的矩阵就是K*K的,这里果断省了一大把时间啊,这么简单的变换为毛我们就是没想到泪奔

    【注意】平时都是用结构体进行快速幂运算,但是要是结构体里的数组太大了就会ce。这里我只有一部分是用的结构体,后一部分用的数组。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<map>
     4 #include<algorithm>
     5 #include<cstring>
     6 #define INF 9999999
     7 using namespace std;
     8 struct node
     9 {
    10     int mat[7][7];
    11 } no;
    12 
    13 int a[1002][7],b[7][1002],cc[1002][1002],aa[1002][7];
    14 
    15 
    16 node mul(node a,node b,int n,int m,int p)
    17 {
    18     node c;
    19     memset(c.mat,0,sizeof(c.mat));
    20     for(int i=0; i<n; i++)
    21         for(int j=0; j<m; j++)
    22             if(a.mat[i][j])
    23             {
    24                 for(int k=0; k<p; k++)
    25                     c.mat[i][k]=(c.mat[i][k]+a.mat[i][j]*b.mat[j][k])%6;
    26             }
    27     return c;
    28 }
    29 
    30 node solve(node a,int num,int n)
    31 {
    32     node b;
    33     memset(b.mat,0,sizeof(b.mat));
    34     for(int i=0; i<n; i++)
    35         b.mat[i][i]=1;
    36     while(num)
    37     {
    38         if(num%2)
    39             b=mul(b,a,n,n,n);
    40         a=mul(a,a,n,n,n);
    41         num/=2;
    42     }
    43     return b;
    44 }
    45 
    46 int main()
    47 {
    48     int n,m;
    49     while(~scanf("%d%d",&n,&m))
    50     {
    51         if(n==0&&m==0)
    52             break;
    53         for(int i=0; i<n; i++)
    54             for(int j=0; j<m; j++)
    55                 scanf("%d",&a[i][j]);
    56 
    57         for(int i=0; i<m; i++)
    58             for(int j=0; j<n; j++)
    59                 scanf("%d",&b[i][j]);
    60 
    61         memset(no.mat,0,sizeof(no.mat));
    62         for(int i=0; i<m; i++)
    63             for(int j=0; j<n; j++)
    64                 if(b[i][j])
    65                 {
    66                     for(int k=0; k<m; k++)
    67                         no.mat[i][k]=(no.mat[i][k]+b[i][j]*a[j][k])%6;
    68                 }
    69 
    70         no=solve(no,n*n-1,m);
    71 
    72         memset(aa,0,sizeof(aa));
    73         for(int i=0; i<n; i++)
    74             for(int j=0; j<m; j++)
    75                 if(a[i][j])
    76                 {
    77                     for(int k=0; k<m; k++)
    78                         aa[i][k]=(aa[i][k]+a[i][j]*no.mat[j][k])%6;
    79                 }
    80 
    81         memset(cc,0,sizeof(cc));
    82         for(int i=0; i<n; i++)
    83             for(int j=0; j<m; j++)
    84                 if(aa[i][j])
    85                 {
    86                     for(int k=0; k<n; k++)
    87                         cc[i][k]=(cc[i][k]+aa[i][j]*b[j][k])%6;
    88                 }
    89         int ans=0;
    90         for(int i=0; i<n; i++)
    91             for(int j=0; j<n; j++)
    92                 ans+=cc[i][j];
    93         printf("%d
    ",ans);
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    ES6学习,持续更新!!!
    如何实现图片自适应
    jquery判断元素是否存在
    JS基础_对象字面量
    JS基础_基本数据类型和引用数据类型
    JS基础_属性名和属性值
    JS基础_对象的简介、对象的基本操作
    JS基础_质数练习的改进,提高程序执行效率
    JS基础_break和continue
    JS基础_打印出1-100之间所有的质数
  • 原文地址:https://www.cnblogs.com/assult/p/3925121.html
Copyright © 2011-2022 走看看