AcWing 798.差分矩阵
题目链接:https://www.acwing.com/problem/content/800/
关于二维差分
若要将二维数组中的某一个矩阵的每个元素的值加上 c,我们可以通过二维差分以达到 O(1) 的时间复杂度。
原数组:a[i][j]
构造差分数组:b[i][j]
也就是说:a数组是b数组的前缀和数组,b数组是a数组的差分数组。
使得a数组中 a[i][j] 是b数组左上角(1,1)到右下角(i,j)所包围矩形元素的和。
如何构造差分数组?
和一维差分一样,我们对b数组中的 b[i][j] 修改后会影响a数组中从 a[i][j] 开始往后的每一个数,而我们只需要对指定矩阵中的元素进行修改。
类比一维差分我们可以这样操作:
b[x1][y1]+=c; b[x1][y2+1]-=c; b[x2+1][y1]-=c; b[x2+1][y2+1]+=c;
对b数组进行处理,即对a数组中(x1,y1)到(x2,y2)之间的元素+c,等价于:
for(int i=x1; i<=x2; i++) for(int j=y1; j<=y2; j++) a[i][j]+=c;
理解如图:
最后计算二维前缀和并输出:
求 a[i][j] 即求 b[i][j] 的前缀和,b[i][j] + = b[i][j-1] + b[i-1][j] - b[i-1][j-1]。
(当我们要计算 b[i][j] 时,在b数组中 b[i][j] 之前的元素值已经成为此点的前缀和)
放AC代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[1005][1005],b[1005][1005];//a前缀和数组,b差分数组 4 int n,m,q; 5 6 void insert(int x1,int y1,int x2,int y2,int c) 7 {//对b数组进行处理,即对a数组中(x1,y1)到(x2,y2)之间的元素+c 8 b[x1][y1]+=c; 9 b[x1][y2+1]-=c; 10 b[x2+1][y1]-=c; 11 b[x2+1][y2+1]+=c; 12 } 13 14 int main() 15 { 16 cin>>n>>m>>q; 17 for(int i=1; i<=n; i++) 18 for(int j=1; j<=m; j++) 19 cin>>a[i][j]; 20 //构造差分数组 21 for(int i=1; i<=n; i++) 22 for(int j=1; j<=m; j++) 23 insert(i,j,i,j,a[i][j]); 24 //对原数组进行操作 25 while(q--) 26 { 27 int x1,y1,x2,y2,c; 28 cin>>x1>>y1>>x2>>y2>>c; 29 insert(x1,y1,x2,y2,c); 30 } 31 //计算二维前缀和 32 for(int i=1; i<=n; i++) 33 for(int j=1; j<=m; j++) 34 b[i][j]+=b[i][j-1]+b[i-1][j]-b[i-1][j-1]; 35 //输出前缀和,即现在的s数组 36 for(int i=1; i<=n; i++) 37 { 38 for(int j=1; j<=m; j++) 39 { 40 cout<<b[i][j]<<" "; 41 } 42 cout<<endl; 43 } 44 return 0; 45 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)