一维前缀和 题目描述
输入一个长度为n的整数序列。 接下来再输入m个询问,每个询问输入一对l, r。 对于每个询问,输出原序列中从第$l$个数到第$r$个数的和。
输入格式 第一行包含两个整数n和m。 第二行包含n个整数,表示整数数列。 接下来m行,每行包含两个整数l和r,表示一个询问的区间范围。
输出格式 共m行,每行输出一个询问的结果。
数据范围 $1<=l<=r<=n$
$1<=n,m<=100000$
$-1000<=$数列中元素的值$<=1000$
题目分析 此类题可以推算出一种公式。
代码实现 #include <bits/stdc++.h> using namespace std ;const int N = 100010 ;int n, m;int a[N], s[N];int main () { scanf ("%d %d" , &n, &m); for (int i = 1 ; i <= n; i++) scanf ("%d" , &a[i]); for (int i = 1 ; i <= n; i++) s[i] = s[i - 1 ] + a[i]; while (m --){ int l, r; scanf ("%d %d" , &l, &r); printf ("%d\n" , s[r] - s[l - 1 ]); } return 0 ; }
运行结果 输入
输出
总结
求前缀和,主要考虑区间端点,根据推算的公式可以将其直接运用,需要注意的是$S_0=0$此处要控制边界。
二维前缀和 题目描述
输入一个n行m列的整数矩阵,再输入q个询问,每个询问包含四个整数x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。
输入格式 第一行包含三个整数n, m,q。 接下来n行,每行包含m个整数,表示整数矩阵。 接下来q行,每行包含四个整数x1,y1,x2,y2,表示一组询问。
输出格式 共q行,每行输出一个询问的结果。
数据范围 $1<=n,m<=1000$
$1<=q<=100000$
$1<=x_1<=x_2<=n$
$1<=y_1<=y_2<=m$
$-1000<=$矩阵内元素的值$<=1000$
题目分析 此类题可以推算出一种公式。
代码实现 #include <bits/stdc++.h> using namespace std ;const int N = 1010 ;int n, m, q;int a[N][N], s[N][N];int main () { scanf ("%d %d %d" , &n, &m, &q); for (int i = 1 ; i <= n; i++) for (int j = 1 ; j <= m; j++) scanf ("%d" , &a[i][j]); for (int i = 1 ; i <= n; i++) for (int j = 1 ; j <= m; 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 ; }
运行结果 输入
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
输出
总结
矩阵序列同样可以通过一维类似的方式进行解决,通过分析图解推导公式最后代入公式即可