构造前缀贪心+ 计蒜客 子矩阵求和
題目:
給出一個 nn 行 mm 列的矩陣,矩陣的每個位置有一個非負整數 a[i][j],有 qq 次詢問,每次詢問求一個左上角為 (a,b),右下角為 (c,d) 的子矩陣的所有數之和。
輸入格式
第一行兩個整數 n,m,表示矩陣的行和列的大小。
接下來 nn 行每行 m 個整數,為矩陣內容。
接下來一行為一個整數 q ,表示詢問次數。
接下來 q 行每行 44 個整數 a,b,c,d,含義見題面。
輸出格式
共 q 行,第 i 行為第 i個詢問的答案。
數據范圍
n×m≤100,000,a[i][j]≤1000,q≤100,000,1≤a≤c≤n,1≤b≤d≤m。n×m≤100,000,a[i][j]≤1000,q≤100,000, 1≤a≤c≤n,1 \le b \le d \le m。n×m≤100,000,a[i][j]≤1000,q≤100,000,1≤a≤c≤n,1≤b≤d≤m。
輸出時每行末尾的多余空格,不影響答案正確性
要求使用「文件輸入輸出」的方式解題,輸入文件為 sum.in,輸出文件為 sum.out
樣例輸入
3 5
1 2 3 4 5
3 2 1 4 7
2 4 2 1 2
3
1 1 3 5
2 2 3 3
1 1 3 3
樣例輸出
43
9
20
分析:
1、先打表計算二維前綴和,再進行之后每次的查詢。
2、需要使用數據結構vector存儲數據。因為n×m≤100,000n×m≤100,000n×m≤100,000,要是開二維數組會爆,所以用vector容器存數據。
如圖所示,假設要求S的話,可以用最大的矩形和減去S1+S2,再減去S1+S3,最后再加上S1即可。
AC代碼:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<vector> using namespace std; const int M=1e5+10; const int inf=0x3f3f3f3f; int n,m,k; vector<int>mp[M]; int main(){freopen("sum.in", "r", stdin);freopen("sum.out", "w", stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){mp[i].push_back(0);for(int j=1;j<=m;j++){int x;scanf("%d",&x);mp[i].push_back(x);}}for(int i=0;i<=m;i++)mp[0].push_back(0);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)mp[i][j]+=mp[i-1][j]+mp[i][j-1]-mp[i-1][j-1];scanf("%d",&k);while(k--){int a,b,c,d;scanf("%d%d%d%d",&a,&b,&c,&d);int ans=mp[c][d]+mp[a-1][b-1]-mp[a-1][d]-mp[c][b-1];printf("%d\n",ans);} } /** 5 5 636 848 745 281 87 895 796 850 713 242 16 128 270 845 922 338 690 30 327 273 779 154 192 656 64 5 2 1 4 2 1 1 1 1 2 1 4 2 2 1 4 2 2 1 2 3 */總結
以上是生活随笔為你收集整理的构造前缀贪心+ 计蒜客 子矩阵求和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开电动车能减肥吗
- 下一篇: 前缀和优化+计蒜客 泡咖啡