差分
本算法题来自acwing 97. 差分 ,以下是要求
要求
输入一个长度为 n 的整数序列。
接下来输入 m 个操作,每个操作包含三个整数 l,r,c,表示将序列中 [l,r]之间的每个数加上 c。
请你输出进行完所有操作后的序列。
输入格式: 第一行包含两个整数 n 和 m 。
第二行包含 n 个整数,表示整数序列。
接下来 m 行,每行包含三个整数 l,r,c ,表示一个操作。
输出格式: 共一行,包含 n 个整数,表示最终序列。
输入样例: 6 3 1 2 2 1 2 1 1 3 1 3 5 1 1 6 1
输出样例: 3 4 5 3 4 2
算法代码
const N = 100010;
let n, m;
let a = new Array(N); // 存储初始数组
let b = new Array(N); // 存储差分数组
function insert(l, r, c) {
// 将区间[l, r]中的元素加上c
b[l] += c;
b[r + 1] -= c;
}
function main() {
// 读入n,m
let input = readline().split(' ').map(Number);
n = input[0], m = input[1]; //控制台输入的值
// 读入初始数组a
input = readline().split(' ').map(Number);
for (let i = 1; i <= n; i++) {
a[i] = input[i - 1];
}
// 对差分数组b进行预处理,初始化为初始数组a
for (let i = 1; i <= n; i++) {
insert(i, i, a[i]);
}
// 对m个操作进行处理
while (m--) {
input = readline().split(' ').map(Number);
let l = input[0], r = input[1], c = input[2];
insert(l, r, c); // 将区间[l, r]中的元素加上c
}
// 根据差分数组b求出最终数组c
for (let i = 1; i <= n; i++) {
b[i] += b[i - 1];
}
// 输出最终数组c
console.log(b.slice(1, n + 1).join(' '));
}
main();
假设原始数组为 [4, 6, 7, 8], 差分数组为 [4, 2, 1, 1]。
对差分数组 b 求前缀和,得到:
c[1] = b[1] = 4
c[2] = b[1] + b[2] = 6
c[3] = b[1] + b[2] + b[3] = 7
c[4] = b[1] + b[2] + b[3] + b[4] = 8
对比一下原始数组,可以看到:
第一项:a[1] = 4,而 c[1] = b[1] = 4,相同。
第二项:a[2] = 6,而 c[2] = b[1] + b[2] = 4 + 2 = 6,相同。
第三项:a[3] = 7,而 c[3] = b[1] + b[2] + b[3] = 4 + 2 + 1 = 7,相同。
第四项:a[4] = 8,而 c[4] = b[1] + b[2] + b[3] + b[4] = 4 + 2 + 1 + 1 = 8,相同。
所以可以发现,前缀和数组 c 就是原始数组 a,其差分数组 b 就是相邻两项之差。
···