二维前缀和
-
S[i,j]即为图1红框中所有数的的和为:
S[i,j]=S[i,j−1]+S[i−1,j]−S[i−1,j−1]+a[i,j]
-
(x1,y1),(x2,y2)这一子矩阵中的所有数之和为:S[x2,y2]−S[x1−1,y2]−S[x2,y1−1]+S[x1−1,y1−1]
代码:
#include <iostream>
using namespace std;
const int N = 1010;
int a[N][N], s[N][N];
int main() {
int n, m, q;
cin >> n >> m >> q;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + a[i][j]; // 求前缀和
}
while (q--) {
int x1,y1,x2,y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
// 算子矩阵的和
printf("%d\n", s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]);
}
return 0;
}
学习总结了一、二维前缀和差分,希望对你有帮助~
https://blog.csdn.net/m0_74215326/article/details/129620912?spm=1001.2014.3001.5502
看完回来的,理解很透彻,非常厉害的一篇题解!!
看完你的评论去看的 的确不错
还是错的,原代码按上去了
没啥问题呀,很清晰。谢谢大佬~
我咋还是超时呢
愚钝的我终于懂了
666
咋还是错的…大佬们帮忙看看啊
#include<iostream> #include<cstdio> using namespace std; int a[1001][1001],x1[200010],y1[200010],x2[200010],y2[200010],d[1001][1001]; int main() { int n,m,q; cin>>n>>m>>q; for(int i = 0;i < n;i ++){ for(int j = 0;j < m;j ++){ cin>>a[i][j];d[i][j]=d[i-1][j]+d[i][j-1]-d[i-1][j-1]+a[i][j]; } } for(int i = 0;i < q;i ++) { cin>>x1[i]>>y1[i]>>x2[i]>>y2[i]; cout<<d[x2[i]-1][y2[i]-1]+d[x1[i]-2][y1[i]-2]-d[x1[i]-2][y2[i]-1]-d[x2[i]-1][y1[i]-2]<<endl; } return 0; }
感觉没问题了啊。。。最后一个数据总是过不了,Wrong Answer
#include<iostream> #include<cstdio> using namespace std; int a[1001][1001],x1[200010],y1[200010],x2[200010],y2[200010],d[1001][1001]; int main() { int n,m,q; cin>>n>>m>>q; for(int i = 1;i <= n;i ++){ for(int j = 1;j <= m;j ++){ cin>>a[i][j];d[i][j]=d[i-1][j]+d[i][j-1]-d[i-1][j-1]+a[i][j]; } } for(int i = 0;i < q;i ++) { cin>>x1[i]>>y1[i]>>x2[i]>>y2[i]; cout<<d[x2[i]][y2[i]]+d[x1[i]-1][y1[i]-1]-d[x1[i]-1][y2[i]]-d[x2[i]][y1[i]-1]<<endl; } return 0; }
i, j 从1开始枚举啊,不然你i=0, j=0的时候,d[0][0]=d[-1][0]+d[0][-1]-.... 下标都越界了。
好的谢谢
ac了
下标越界了- -
超时,改成scanf试一试就行了,数据太多了cin输入的速度太慢了,用scanf快一倍。
因为输入数据,x1肯比x2还大
13届原题
牛逼
good
#include[HTML_REMOVED]
using namespace std;
const int N=1010;
int a[N][N];
signed main()
{
int n,m,q;
cin>>n>>m>>q;
for(int i=1;i<=n;i){
for(int j=1;j<=m;j){
cin>>a[i][j];
a[i][j]+=a[i][j-1];
}
}
int x1,x2,y1,y2;
while(q–){
long long sum=0;
cin>>x1>>y1>>x2>>y2;
for(int i=y1;i<=y2;i++){
sum+=(a[i][x2]-a[i][x1-1]);
}
cout<<sum<<endl;
}
}
能不能来个大佬告诉我哪里不对,谢了。
看懂了,给大佬磕一个
这里的q有什么用啊
就需要有这样的图,否则真的是有点蒙
图上的坐标对应的是小方格,而不是点,y总视频画的图确实有些误导
很清楚!谢谢佬
请问时间复杂度是n^2吗
时间复杂度是O(n),每次迭代最多n次,总的应该是O(2n),所以就是O(n)。
谢谢你
谢谢大佬
姐,是不是每个给定的二维数组的隐含着a[0][j]=0和a[i][0]=0和a[0][0]=0的数值啊
全局变量默认是0
谢谢这个晓得
点赞