南昌网站建设博客,邯郸品牌商标vi设计策划公司,常熟seo关键词优化公司,最新采购求购信息网站前缀和前缀和子矩阵的和结语前缀和
输入一个长度为 n的整数序列。
接下来再输入 m 个询问#xff0c;每个询问输入一对 l,r
对于每个询问#xff0c;输出原序列中从第 l 个数到第 r个数的和。
输入格式第一行包含两个整数 n和 m
第二行包含 n个整数#xff0c;表示整数…
前缀和前缀和子矩阵的和结语前缀和
输入一个长度为 n的整数序列。
接下来再输入 m 个询问每个询问输入一对 l,r
对于每个询问输出原序列中从第 l 个数到第 r个数的和。
输入格式第一行包含两个整数 n和 m
第二行包含 n个整数表示整数数列。
接下来 m行每行包含两个整数 l 和 r表示一个询问的区间范围。
输出格式共 m 行每行输出一个询问的结果。
数据范围 1≤l≤r≤n , 1≤n,m≤100000 , −1000≤数列中元素的值≤1000 输入样例
5 3
2 1 3 6 4
1 2
1 3
2 4输出样例
3
6
10前缀和的用处前缀和数组能以On(1)的方式求出给定范围内数组的和。
在很多地方都用的上前缀和数组只是它很容易被人忽略所以得多练练加深印象。
解题思路本题是一维数组的前缀和思路很简单直接在原数组上进行修改即可。
求前缀和数组设原数组为a[],我们可知递推方程为a[i]a[i-1]a[i]
前缀和数组求出后要知道给定范围内[i,j]的数组和就很简单了 方程为 vlaa[j]-a[i-1]
代码
#includeiostreamusing namespace std;const int N100010;
int a[N];
int b[N];int main()
{int n,m;scanf(%d%d,n,m);for(int i1;in;i) scanf(%d,a[i]);for(int i1;in;i) a[i]a[i-1]a[i];while(m--){int l,r;scanf(%d%d,l,r);couta[r]-a[l-1]endl;}
}子矩阵的和
输入一个 n 行 m 列的整数矩阵再输入 q 个询问每个询问包含四个整数 x1,y1,x2,y2表示一个子矩阵的左上角坐标和右下角坐标。 对于每个询问输出子矩阵中所有数的和。 输入格式 第一行包含三个整数 nmq
接下来 n 行每行包含 m 个整数表示整数矩阵。
接下来 q行每行包含四个整数 x1,y1,x2,y2表示一组询问。
输出格式 共 q行每行输出一个询问的结果。
数据范围
1≤n,m≤1000
,
1≤q≤200000
,
1≤x1≤x2≤n
,
1≤y1≤y2≤m
,
−1000≤矩阵内元素的值≤1000输入样例
3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4输出样例
17
27
21本题大致意思同上题差不多只是从一维数组变为二维数组有些不太好理解
要求给定范围内的数组和 先说求二维前缀和的递推公式
a[i][j]a[i][j-1]a[i-1][j]-a[i-1][j-1]a[i][j];看图 黑颜色即为所求但是当我们在减去多余部分的时候有一块区域会被减去两次如上图就是橙色的区域因此我们需要将其加回来。 代码
#includeiostreamusing namespace std;const int N1010;
int a[N][N];int main()
{int n,m,q;scanf(%d%d%d,n,m,q);for(int i1;in;i){for(int j1;jm;j){scanf(%d,a[i][j]);}}for(int i1;in;i){for(int j1;jm;j){a[i][j]a[i][j-1]a[i-1][j]-a[i-1][j-1]a[i][j];}}while(q--){int x1,y1,x2,y2;scanf(%d%d%d%d,x1,y1,x2,y2);int vala[x2][y2]-a[x2][y1-1]-a[x1-1][y2]a[x1-1][y1-1];coutvalendl;}return 0;
}结语
下篇会描述前缀和的兄弟差分数组。
如果觉得有帮助的话记得 一键三连哦ヾ(≧▽≦*)o。