zoukankan      html  css  js  c++  java
  • 矩阵乘法2(codevs3147)

    题目描写叙述 Description
    给出两个n*n的矩阵。m次询问它们的积中给定子矩阵的数值和。

    输入描写叙述 Input Description
    第一行两个正整数n,m。


    接下来n行,每行n个非负整数。表示第一个矩阵。
    接下来n行,每行n个非负整数。表示第二个矩阵。
    接下来m行。每行四个正整数a。b,c,d,表示询问第一个矩阵与第二个矩阵的积中。
    以第a行第b列与第c行第d列为顶点的子矩阵中的元素和。

    输出描写叙述 Output Description
    对每次询问,输出一行一个整数。表示该次询问的答案。
    例子输入 Sample Input
    3 2
    1 9 8
    3 2 0
    1 8 3
    9 8 4
    0 5 15
    1 9 6
    1 1 3 3
    2 3 1 2

    例子输出 Sample Output
    661
    388
    数据范围及提示 Data Size & Hint
    【数据规模和约定】

    对30%的数据满足,n <= 100。
    对100%的数据满足。n <= 2000,m <= 50000,输入数据中矩阵元素 < 100,a。b。
    c,d <= n。


    题解:
    这个题尽管名字是矩阵乘法。可是和矩阵高速幂一点关系也没有。。


    30%做法:
    直接两个矩阵暴力相乘,然后再暴力询问。(ps:集训队的题居然给这么多暴力分)
    100%做法:
    如果你对矩阵乘法足够了解的话。能够发现我们事实上能够在O(n)的复杂度内处理出每次询问。
    设要求和的矩阵为A(x1,x2,y1,y2);第一个矩阵为a,第二个矩阵为b那么矩阵A能够分行来计算
    如果A矩阵第一行(x1)的元素为p[i];
    那么依据矩阵乘法的法则
    p[i]等于a矩阵的第X1行的元素和b矩阵的第i列的元素相应相乘。再相加。


    sigma{p[i]}(y1<=i<=y2)为a矩阵的第X1行的元素分别和b矩阵的第y1到y2列的元素相应相乘,再相加。
    那么我们能够发现这个式子能够使用乘法结合律提出a矩阵第x1行的元素。再用第i个元素与b矩阵第i列的和相乘,最后把所得的乘积相加,
    同理第二行第三行也都一样,
    我们会发现不同行之间也能够提取出b矩阵中每一列的和,
    那么最后所询问矩阵的和就为a矩阵第x1-x2行每行的元素和与b矩阵第y1-y2列的每列的元素和相应相乘再相加。
    所以仅仅要预处理出a矩阵每一行的前缀和
    b矩阵每一列的前缀和就可以
    时间复杂度O(n^2+n*m);
    注意使用scanf或读入优化。
    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define For(i,n) for(int i=1;i<=n;i++)  
    #define read(x) scanf("%d",&x); 
    int n,m,x,y,xx,yy,aa[2001][2001]={0},bb[2001][2001]={0},a,b;
    int main()
    {
        read(n);read(m);
        For(i,n) For(j,n)
        {
             read(a);
             aa[i][j]=aa[i-1][j]+a;
        }
        For(i,n) For(j,n)
            {
              read(b);
              bb[i][j]=bb[i][j-1]+b;
            }
         For(i,m)
           {
             read(x);read(y);read(xx);read(yy);
             long long ans=0;
             if (x>xx) swap(x,xx);
             if (y>yy) swap(y,yy); 
             For(j,n)
               ans+=(long long)(aa[xx][j]-aa[x-1][j])*(long long)(bb[j][yy]-bb[j][y-1]);
             printf("%lld
    ",ans);
           }
    }
    
  • 相关阅读:
    浅谈表单同步提交和异步提交
    springboot多数据源&动态数据源(主从)
    MyBatis 中 @Param 注解的四种使用场景,最后一种经常被人忽略!
    手把手带你入门 Spring Security!
    10分钟了解JSON Web令牌(JWT)
    什么是Http无状态?Session、Cookie、Token三者之间的区别
    彻底理解cookie,session,token的区别
    56.合并区间(面试遇到的一道算法题,简述解法)
    C#object
    职称考试整理
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6946570.html
Copyright © 2011-2022 走看看