差分

1.一维模板题

797. 差分 - AcWing题库

输入一个长度为 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

输入样例:

1
2
3
4
5
6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1

输出样例:

1
3 4 5 3 4 2

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* 797. 差分
* https://www.acwing.com/problem/content/799/
*
* @author yangxiaozhuo
* @date 2023/02/16
*/
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String[] s = in.readLine().split(" ");
int n = Integer.parseInt(s[0]);
int T = Integer.parseInt(s[1]);
s = in.readLine().split(" ");
int[] nums = new int[n + 2];
for (int i = 0; i < n; i++) {
nums[i + 1] = Integer.parseInt(s[i]);
}
int[] div = new int[n + 2];
while (T-- > 0) {
s = in.readLine().split(" ");
int a = Integer.parseInt(s[0]);
int b = Integer.parseInt(s[1]);
int x = Integer.parseInt(s[2]);
div[a] += x;
div[b + 1] -= x;
}
StringBuilder sb = new StringBuilder();
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += div[i];
sb.append(sum + nums[i]);
sb.append(" ");
}
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb.toString());
}
}

2.二维模板题

798. 差分矩阵 - AcWing题库

输入一个 n 行 m列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。

每个操作都要将选中的子矩阵中的每个元素的值加上 c。

请你将进行完所有操作后的矩阵输出。

输入格式

第一行包含整数 n,m,q。

接下来 n行,每行包含 m 个整数,表示整数矩阵。

接下来 q 行,每行包含 55 个整数 x1,y1,x2,y2,c表示一个操作。

输出格式

共 n 行,每行 m 个整数,表示所有操作进行完毕后的最终矩阵。

数据范围

1≤n,m≤1000

1≤q≤100000

1≤x1≤x2≤n

1≤y1≤y2≤m

−1000≤c≤1000−1000≤≤1000, &#x20;

−1000≤矩阵内元素的值≤1000

输入样例:

1
2
3
2 3 4 1
4 3 4 1
2 2 2 2

输出样例:

1
2
3
3
6
10

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
* 798. 差分矩阵
* https://www.acwing.com/problem/content/800/
*
* @author yangxiaozhuo
* @date 2023/02/16
*/
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String[] s = in.readLine().split(" ");
int n = Integer.parseInt(s[0]);
int m = Integer.parseInt(s[1]);
int q = Integer.parseInt(s[2]);
int[][] num = new int[n + 1][m + 1];
for (int i = 1; i <= n; i++) {
s = in.readLine().split(" ");
for (int j = 1; j <= m; j++) {
num[i][j] = Integer.parseInt(s[j - 1]);
}
}
int[][] div = new int[n + 2][m + 2];
while (q-- > 0) {
s = in.readLine().split(" ");
int x1 = Integer.parseInt(s[0]);
int y1 = Integer.parseInt(s[1]);
int x2 = Integer.parseInt(s[2]);
int y2 = Integer.parseInt(s[3]);
int val = Integer.parseInt(s[4]);
div[x1][y1] += val;
div[x1][y2 + 1] -= val;
div[x2 + 1][y1] -= val;
div[x2 + 1][y2 + 1] += val;
}
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= n; i++) {
sb = new StringBuilder();
for (int j = 1; j <= m; j++) {
div[i][j] = div[i][j - 1] + div[i - 1][j] - div[i - 1][j - 1] + div[i][j];
num[i][j] += div[i][j];
sb.append(num[i][j]);
sb.append(" ");
}
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb.toString());
}
}
}

3.一维训练题

3729. 改变数组元素 - AcWing题库

给定一个空数组 V 和一个整数数组 a1,a2,…,an

现在要对数组 V 进行 n 次操作。

第 i次操作的具体流程如下:

  1. 从数组 V 尾部插入整数 00。
  2. 将位于数组 V 末尾的 ai个元素都变为 11(已经是 11 的不予理会)。

注意:

  • ai 可能为 00,即不做任何改变。
  • ai可能大于目前数组 V 所包含的元素个数,此时视为将数组内所有元素变为 11。

请你输出所有操作完成后的数组 V。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含整数 n。

第二行包含 n 个整数 a1,a2,…,an

输出格式

每组数据输出一行结果,表示所有操作完成后的数组 V,数组内元素之间用空格隔开。

数据范围

1≤T≤20000
1≤n≤2×105
0≤ai≤n
保证一个测试点内所有 n 的和不超过 2×1052×105。

输入样例:

1
2
3
4
5
6
7
3
6
0 3 0 0 1 3
10
0 0 0 1 0 5 0 0 0 2
3
0 0 0

输出样例:

1
2
3
1 1 0 1 1 1
0 1 1 1 1 1 0 0 1 1
0 0 0

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
* 3729. 改变数组元素
* https://www.acwing.com/problem/content/3732/
*
* @author yangxiaozhuo
* @date 2023/02/16
*/
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(in.readLine());
while (T-- > 0) {
int n = Integer.parseInt(in.readLine());
String[] s = in.readLine().split(" ");
int[] nums = new int[n];
for (int i = 0; i < nums.length; i++) {
nums[i] = Integer.parseInt(s[i]);
}
fun(nums, n);
}
}

private static void fun(int[] nums, int n) {
int[] div = new int[n + 1];
for (int i = 0; i < nums.length; i++) {
div[i + 1]--;
div[Math.max(0, i - nums[i] + 1)]++;
}
StringBuilder res = new StringBuilder();
int sum = 0;
for (int i = 0; i < div.length - 1; i++) {
sum += div[i];
if (sum > 0) {
res.append(1);
} else {
res.append(0);
}
res.append(" ");
}
res.deleteCharAt(res.length() - 1);
System.out.println(res.toString());
}
}