大家好,我是晴天学长,今天的题目类型是前缀和的亲戚(差分),两个互逆,实际运用非常广泛,加油!需要的小伙伴请自取哦!💪💪💪
1 )小明的彩灯
2) .算法思路
小明的彩灯
N个彩灯 i个彩灯的初始亮度为ai
Q次操作 让一段区间的亮度增加x(x可能为负数)
问Q次后每个彩灯的亮度
数据接收:
1.接收N,Q 彩灯数量 操作次数
2.N个彩灯的初始亮度
3.Q次操作 l r x 表示将区间 l∼r 的彩灯的亮度 +x
算法:
1.用快读接收数据,用快输输出数据
2.建立N+1大小的数组(问的l,r,但数组又是从下标0开始的,所以+1)
3.建立N+2大小的差分数组(同理),但是r+1要判定一下,防止越界。
ok,一排一排的接入数据,差分+复原(a[i] = c[i]+a[i-1])
差分计算(){
一定是两个,要记住模板
c[l] = x;
c[r+1] - = x; x有正有负
}
3).代码示例
package LanQiaoTest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class 小明的彩灯 {
public static void main(String[] args) throws IOException {
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String[] s = in.readLine().split(" ");
int N = Integer.parseInt(s[0]);//次数
int Q = Integer.parseInt(s[1]);//个数
//建立数组
long[] a = new long[N+1];
long[] c = new long[N+1];
//读入数据,从1开始
s = in.readLine().split(" ");
for (int i = 1; i < a.length ; i++) {
a[i]= Long.parseLong(s[i-1]);
}
//差分
for (int i = 1; i < a.length; i++) {
c[i] = a[i]-a[i-1];
}
for (int i = 0; i < Q ; i++) {
s= in.readLine().split(" ");
int l = Integer.parseInt(s[0]);
int r = Integer.parseInt(s[1]);
long x = Long.parseLong(s[2]);
check(l, r, x, c);
}
//数组的复原
for (int i = 1; i < c.length; i++) {
a[i] = c[i] + a[i-1];
}
//打印
for (int i = 1; i < a.length; i++) {
if (a[i]>0) {
out.print(a[i]+" ");
}
else {
out.print("0"+" ");
}
}
out.flush();
}
//数组的差分计算,数组下标最多为int
private static void check(int l,int r ,long x,long[] c) {
c[l] += x;
if(!(r==c.length-1)) {
c[(r+1)]-=x;
}
}
}
3 .)总结
- 差分就是在o(1)的复杂度内在某段区间±x;
- 差分计算一定是两个,要记住模板
c[l] = x;
c[r+1] - = x; x有正有负