一、一维前缀和
int n, m, l, r;
int a[N], s[N];
int main()
{
cin>>n;
for (int i = 1; i <= n; i ++ )
{
cin >> a[i];
s[i] = s[i - 1] + a[i]; // 前缀和的初始化,在一维前缀和中可以一边录入一边计算前缀和数组
}
cin >> l >> r;
cout<< s[r] - s[l - 1]; // 区间和的计算公式
return 0;
}
二、二维前缀和
int n, m, q;
int s[N][N];
int main()
{
cin>>n>>m;
for (int i = 1; i <= n; i ++ )
{
for (int j = 1; j <= m; j ++ )
{
scanf("%d", &s[i][j]);
}
}
for (int i = 1; i <= n; i ++ )
{
for (int j = 1; j <= m; j ++ )
{
s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];//与一维前缀和不同的是,二维前缀和需要先将所有数录入,再计算前缀和
//注意:::二维前缀和中间是 +=
}
}
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);//对于 (x1,y1) 到 (x2,y2) 这部分的和
//从 (x1,y1) 到 (x2,y2) 实际上是边长为 n=x2-x1+1 和 m=y2-y1+1 的矩形,所以和还可以是
// s[x2][y2]-s[x2-n][y2]-s[x2][y2-m]+s[x2-n][y2-m]
return 0;
}
三、一维差分
差分是前缀和的逆运算,将所给数组视为前缀和,求原数组
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N],b[N];
int main()
{
int n,m;
scanf("%d%d", &n, &m);
for(int i = 1;i <= n; i++)
{
scanf("%d", &a[i]);
b[i] = a[i] - a[i - 1]; //构建差分数组的公式
}
int l, r, c;
scanf("%d%d%d", &l, &r, &c);
b[l] += c; //表示将序列中[l, r]之间的每个数加上c,差分的题通常需要这样
b[r + 1] -= c; //这两行是公式
for(int i = 1;i <= n; i++)
{
b[i] += b[i - 1]; //求前缀和运算,新的b数组就是对a执行完操作后的数组
printf("%d ",b[i]);
}
return 0;
}