基本思想:
前缀和的思想很简单,可以理解为数学上的数列的前n项和,多用于求区间和,子矩阵和等问题。
而差分则是前缀和的逆运算,我们可以通过差分用O(1)的复杂度给一个子区间±值
对差分数组求它们的前缀和就可以得到原数组
输入一个长度为 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
#include<iostream> using namespace std; const int N = 100010; int n, m, a[N]; int main() { cin >> n >> m; for(int i = 1; i <= n; i++) { cin >> a[i]; a[i] += a[i - 1]; } while(m--) { int l, r; cin >> l >> r; cout << a[r] - a[l - 1] << endl; } return 0; }
输入一个长度为 n 的整数序列。
接下来输入 m 个操作,每个操作包含三个整数 l,r,c 表示将序列中 [l,r] 之间的每个数加上 c
请你输出进行完所有操作后的序列。
输入格式
第一行包含两个整数 n 和 m。
第二行包含 n 个整数,表示整数序列。
接下来 m 行,每行包含三个整数 l,r,c 表示一个操作。
输出格式
共一行,包含 n 个整数,表示最终序列。
数据范围
1≤n,m≤100000
1≤l≤r≤n
−1000≤c≤1000
−1000≤整数序列中元素的值≤1000
输入样例:
6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1
输出样例:
3 4 5 3 4 2
#include<iostream> using namespace std; const int N=1e5+10; int a[N], b[N]; void insert(int l, int r, int c) { b[l] += c; b[r+1] -= c; } int main() { int n,m; scanf("%d%d",&n,&m);//scanf读取的更快 for(int i=1;i<=n;i++) scanf("%d",&a[i]); //b[1]=a[1]; //for(int i=2;i<=n;i++) b[i]=a[i]-a[i-1]; for(int i = 1; i <= n; i++) insert(i,i,a[i]);//和上同样构造b[i] while(m--) { int l, r, c; scanf("%d%d%d",&l,&r,&c); insert(l, r, c); } for(int i = 1; i <= n; i++) b[i] += b[i - 1];//自己把变成自己的前缀和 即变为数组a for(int i = 1; i <= n; i++) cout << b[i] << " "; return 0; }
例题:
1248. 统计「优美子数组」 - 力扣(LeetCode)
//上面三道题都是哈希表和前缀和的综合运用 需要一点头脑(我没有哈哈)