Description
给出两个n*n的矩阵,m次询问它们的积中给定子矩阵的数值和。
Input
接下来n行,每行n个非负整数,表示第一个矩阵。
接下来n行,每行n个非负整数,表示第二个矩阵。
接下来m行,每行四个正整数a,b,c,d,表示询问第一个矩阵与第二个矩阵的积中,以第a行第b列与第c行第d列为顶点的子矩阵中的元素和。
Output
对每次询问,输出一行一个整数,表示该次询问的答案。
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
ps:用VC++提交
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
typedef __int64 ll ;
ll a[2005][2005],b[2005][2005];
//ll sufa[2005][2005];//求矩阵a每一列的前缀和
//ll sufb[2005][2005];//求矩阵b每一行的前缀和
//矩阵a*b的和=a的第一列*b的第一行+a的第二列*b的第二行+……
ll Scan()
{ // 输入外挂
ll res = 0, flag = 0;
char ch;
if ((ch = getchar()) == '-')
{
flag = 1;
}
else if(ch >= '0' && ch <= '9')
{
res = ch - '0';
}
while ((ch = getchar()) >= '0' && ch <= '9')
{
res = res * 10 + (ch - '0');
}
return flag ? -res : res;
}
void Out(ll a)
{ // 输出外挂
if (a < 0)
{
putchar('-');
a = -a;
}
if (a >= 10)
{
Out(a / 10);
}
putchar(a % 10 + '0');
}
int main()
{
int n,m,i,j;
//memset(sufa,0,sizeof(sufa));
//memset(sufb,0,sizeof(b));
n=Scan();
m=Scan();
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
a[i][j]=Scan();
a[i][j]=a[i-1][j]+a[i][j];
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
b[i][j]=Scan();
b[i][j]=b[i][j-1]+b[i][j];
}
while(m--)
{
ll ans=0;
ll x1,x2,y1,y2;
x1=Scan();
y1=Scan();
x2=Scan();
y2=Scan();
for(i=1;i<=n;i++)
{
ll aa,bb;
if(x2>x1)
aa=a[x2][i]-a[x1-1][i];
else aa=a[x1][i]-a[x2-1][i];
if(y2>y1)
bb=b[i][y2]-b[i][y1-1];
else
bb=b[i][y1]-b[i][y2-1];
ans=ans+aa*bb;
}
Out(ans);
printf("\n");
}
return 0;
}