【codevs3147】矩阵乘法2,”名“不副”实“

来源:互联网 发布:淘宝联盟使用红包 编辑:程序博客网 时间:2024/05/01 06:30

传送门


写在前面:一道破题又卡int又卡内存,有没有王法了!
思路:只要懂得矩阵乘法的原理再思考一下就可以了,根本没有什么建初始矩阵求转移矩阵。 如果我们将矩阵A,B相乘再求和,那么O(n^3)的矩阵乘法就把你卡死了,所以我们肯定不能求和。
对于每一次询问,求(x1,y1)到(x2,y2)的矩阵和,我们有
这里写图片描述
所以我们读入时搞个前缀和,然后就可以在O(n^2+n*m)下搞出来了
注意:1.前缀和相乘时千万要先赋值给long long再乘,不能数组开long long!也不能直接用int相乘再加到ans里!
2.不要开存矩阵的数组!直接加到前缀和里,不然也会MLE

#include<bits/stdc++.h>using namespace std;int n,m;int sum_a[2001][2001],sum_b[2001][2001];long long p1,p2;int in(){    char ch=getchar();    int ans=0;    while (ch>'9'||ch<'0') ch=getchar();    while (ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();    return ans;}main(){    n=in();    m=in();    for (int i=1;i<=n;i++)    for (int j=1;j<=n;j++)    sum_a[i][j]=sum_a[i-1][j]+in();    for (int i=1;i<=n;i++)    for (int j=1;j<=n;j++)    sum_b[i][j]=sum_b[i][j-1]+in();    for (int i=1;i<=m;i++)    {        long long ans=0;        int x1,x2,y1,y2;        x1=in();y1=in();        x2=in();y2=in();        if (x1>x2) swap(x1,x2);        if (y1>y2) swap(y1,y2);        for (int k=1;k<=n;k++)        {            p1=sum_a[x2][k]-sum_a[x1-1][k],p2=sum_b[k][y2]-sum_b[k][y1-1];            ans+=p1*p2;        }        printf("%lld\n",ans);    }}
1 0