矩阵乘法2 (Codevs No.3147)

Posted Neptune

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵乘法2 (Codevs No.3147)相关的知识,希望对你有一定的参考价值。

2016-06-01 17:33:30

题目链接: 矩阵乘法2 (Codevs No.3147)

题目大意:

  给定两个大小相同的正方形矩阵A,B.多次询问,每次求乘后矩阵的一个子矩阵所有元素的和.

解法:

  首先想到暴力.

    预处理N^3,询问模拟扫,这常数简直瞬间爆炸啊

  当然是可以优化的.

    列出子矩阵的元素表达式,就会发现有一些元素//矩阵乘法2 (Codevs No.3147)
//矩阵乘法
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=2010;
int map1[maxn][maxn];
int map2[maxn][maxn];
long long ans;
int N,M;
int a,b,c,d;
int main()
{
    scanf("%d %d",&N,&M);
    for(int i=1;i<=N;i++)
    {
        for(int j=1;j<=N;j++)
        {
            scanf("%d",&map1[i][j]);
            map1[i][j]+=map1[i-1][j];
        }
    }
    for(int i=1;i<=N;i++)
    {
        for(int j=1;j<=N;j++)
        {
            scanf("%d",&map2[i][j]);
            map2[i][j]+=map2[i][j-1];
        }
    }
    for(int i=1;i<=M;i++)
    {
        ans=0;
        scanf("%d %d %d %d",&a,&b,&c,&d);
        for(int i=1;i<=N;i++)
        {
            int sumxmap2=map2[i][max(b,d)]-map2[i][min(b,d)-1];
            int sumymap1=map1[max(a,c)][i]-map1[min(a,c)-1][i];
            ans+=(long long)sumxmap2*sumymap1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}的乘积可以做乘法分配律

    所以直接放弃求出子矩阵的确切值,按照分配律的特点组合数据.

    我们对A(乘法的时候乘行)进行列前缀和,对B(乘法的时候乘列)进行行前缀和

    最后所有元素的和就可以表示成sigma((A[i][Dbound]-A[i][Ubound-1])*(B[i][Rbound]-B[i][Lbound-1]));

    (Ubound,Dbound,Lbound,Rbound表示小矩阵的上下左右)

 1 //矩阵乘法2 (Codevs No.3147)
 2 //矩阵乘法
 3 #include<stdio.h>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=2010;
 7 int map1[maxn][maxn];
 8 int map2[maxn][maxn];
 9 long long ans;
10 int N,M;
11 int a,b,c,d;
12 int main()
13 {
14     scanf("%d %d",&N,&M);
15     for(int i=1;i<=N;i++)
16     {
17         for(int j=1;j<=N;j++)
18         {
19             scanf("%d",&map1[i][j]);
20             map1[i][j]+=map1[i-1][j];
21         }
22     }
23     for(int i=1;i<=N;i++)
24     {
25         for(int j=1;j<=N;j++)
26         {
27             scanf("%d",&map2[i][j]);
28             map2[i][j]+=map2[i][j-1];
29         }
30     }
31     for(int i=1;i<=M;i++)
32     {
33         ans=0;
34         scanf("%d %d %d %d",&a,&b,&c,&d);
35         for(int i=1;i<=N;i++)
36         {
37             int sumxmap2=map2[i][max(b,d)]-map2[i][min(b,d)-1];
38             int sumymap1=map1[max(a,c)][i]-map1[min(a,c)-1][i];
39             ans+=(long long)sumxmap2*sumymap1;
40         }
41         printf("%lld\n",ans);
42     }
43     return 0;
44 }

 

以上是关于矩阵乘法2 (Codevs No.3147)的主要内容,如果未能解决你的问题,请参考以下文章

矩阵乘法快速幂 codevs 1250 Fibonacci数列

矩阵乘法 codevs 1287 矩阵乘法

Codevs1732-矩阵乘法快速幂

codevs 3332 数列 (矩阵乘法)

codevs矩阵乘法系列

codevs1281 矩阵乘法 快速幂 !!!手写乘法取模!!! 练习struct的构造函数和成员函数