intmain() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; for ( int i = 1; i <= n; i ++ ) cin >> a[i]; for ( int i = 1; i <= n; i ++ ) s[i] = s[i - 1] + a[i]; // 预处理前缀和数组 while( m -- ){ int l, r; cin >> l >> r; cout << s[r] - s[l - 1] << endl; // 计算区间和 } return0; }
计算前缀和, 得到最终的结果数组 b = {0, 2, 2, 2, 0}, 这个数组就是原始数组 a 在区间 [1, 5] 的累积和.
总结公式: 这里根据 a[ ] 数组, 构造 b[ ] 数组, 使得 a 是 b 的前缀和
// 给区间 [l, r] 中的每个数加上 c voidinsert(int l, int r, int c) { b[l] += c; b[r + 1] -= c; }
一维差分应用: 复杂度由 O(n) 降为 O(1)
#include<bits/stdc++.h> usingnamespace std;
constint N = 100010; int n, m; int a[N], b[N];
voidinsert(int l, int r, int c) { b[l] += c; b[r + 1] -= c; }
intmain() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m; for ( int i = 1; i <= n; i ++ ){ cin >> a[i]; insert(i, i, a[i]); // 构造, 预处理差分数组 } while ( m -- ){ int l, r, c; cin >> l >> r >> c; insert(l, r, c); // 进行区间修改 } for ( int i = 1; i <= n; i ++ ){ b[i] += b[i - 1]; // 计算一维前缀和 cout << b[i] << " "; } cout << endl; return0; }