输入一个长度为 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
1.差分是求前缀和的逆操作,对于原数组a[n]
,构造出一个数组b[n]
,使a[n]
为b[n]
的前缀和。
2.一般用于快速对整个数组进行操作,比如对将a数组
中[l,r]
部分的数据全部加上c
。使用暴力枚举的方法的话,时间复杂至少为O(n)
,而使用差分算法可以将时间复杂度降低到O(1)
。
构造数组如下:
a[0 ]= 0;
b[1] = a[1] - a[0];
b[2] = a[2] - a[1];
b[3] =a [3] - a[2];
........
b[n] = a[n] - a[n-1];
构造代码
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
b[i] = a[i] - a[i - 1]; //构建差分数组
}
完整提交代码:
import java.io.*;
import java.util.*;
public class Main
{
static int N = 100010;
static int [] a = new int [N];
static int [] b = new int [N];
static void insert(int l, int r, int c)
{
b[l] += c;
b[r + 1] -= c;
}
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String [] strs = reader.readLine().trim().split(" ");
int n = Integer.parseInt(strs[0]);
int q = Integer.parseInt(strs[1]);
strs = reader.readLine().trim().split(" ");
for (int i = 1; i <= n; ++ i) {
a[i] = Integer.parseInt(strs[i - 1]);
insert(i, i, a[i]);
}
while(q -- > 0)
{
int l, r, c;
strs = reader.readLine().trim().split(" ");
l = Integer.parseInt(strs[0]);
r = Integer.parseInt(strs[1]);
c = Integer.parseInt(strs[2]);
insert(l, r, c);
}
for (int i = 1; i <= n; ++ i) a[i] = a[i - 1] + b[i];
for (int i = 1; i <= n; ++ i) System.out.print(a[i] + " ");
}
}