差分:
- 一维差分:
原数组:
a1,a2,a3,…an;
构造数组
b1,b2,b3,…bn;
关系:
a1 = b1;
a2 = b1+b2;
b3 = b1+b2+b3;
…
bn = b1+b2+…bn;
则利用b数组就会将a数组进行求解出来。
如果a数组想要进行变动:
只需要进行b数组的一些变动
例如
|____|__||
a数组的[l,r]区间内部想要进行加c则需要全部进行遍历,但是如果是
有差分数组,则,只需要给bl+c,则后面的全部就可以j加c,但是在r+1的地-c。
模板:
给区间[l, r]中的每个数加上c:B[l] += c, B[r + 1] -= c
题目:
https://www.acwing.com/problem/content/description/799/
import java.util.Scanner;
public class Main {
static int Number = 100010;
static int[] A = new int[Number];
static int[] b = new int[Number];
public static void insert(int l,int r,int c){
b[l] = b[l]+c;
b[r+1] = b[r+1]-c;
}
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
//数组
for(int i=1;i<=n;i++){
A[i] = sc.nextInt();
}
//初始化数组和后面的差分数组的效果一样
//初始化时正好后面的可以和前面的相加一致
for(int j=1;j<=n;j++){
insert(j,j,A[j]);//前面加上c后面减去c再加到一起正好是原数组
}
//区间段和c的输入
for(int i=0;i<m;i++){
int l = sc.nextInt();
int r = sc.nextInt();
int c = sc.nextInt();
insert(l,r,c);
}
//经过一系列的顺序指导
for(int i = 1;i<=n;i++){
b[i] = b[i]+b[i-1];
System.out.print(b[i]+" ");
}
}
}
- [ ]二维差分
类似于一维差分和前缀和
首先先构造一个差分矩阵。b
b= f-1(a)
vector – ArrayList,HashMap,LinkedList
2. 核心是怎么相减
代码
public static void insert(int x1,int y1,int x2,int y2,int c){
//使用
B[x1][y1] = B[x1][y1]+c;
B[x2+1][y1] = B[x2+1][y1]-c;
B[x1][y2+1] = B[x1][y2+1]-c;
B[x2+1][y2+1] = B[x2+1][y2+1]+c;
import java.io.*;
import java.util.Scanner;
/*输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c,
其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。
每个操作都要将选中的子矩阵中的每个元素的值加上 c。
请你将进行完所有操作后的矩阵输出。
输入格式
第一行包含整数 n,m,q。
接下来 n 行,每行包含 m 个整数,表示整数矩阵。
接下来 q 行,每行包含 5 个整数 x1,y1,x2,y2,c,表示一个操作。*/
//1≤n,m≤1000,
public class Main {
static int Num = 1010;
static int[][] A = new int[Num][Num];
static int[][] B = new int[Num][Num];
public static void insert(int x1,int y1,int x2,int y2,int c){
//使用
B[x1][y1] = B[x1][y1]+c;
B[x2+1][y1] = B[x2+1][y1]-c;
B[x1][y2+1] = B[x1][y2+1]-c;
B[x2+1][y2+1] = B[x2+1][y2+1]+c;
}
public static void main(String[] args) throws IOException {
//scanner超时-使用Buff
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
//使用buff进行输入输出
//输入是字符串
String[] str = reader.readLine().split(" ");//一串数组
//分别拆开
int n = Integer.valueOf(str[0]);
int m = Integer.valueOf(str[1]);
int q = Integer.valueOf(str[2]);
//
for(int i=1;i<=n;i++){
String[] str2 = reader.readLine().split(" ");//一行换行符
for(int j =1;j<=m;j++){
A[i][j] = Integer.valueOf(str2[j-1]);//1-1=0,2-1=1,3-1=2,4-1=3;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
insert(i,j,i,j,A[i][j]);
}
}
//初始化结束
//输入下一个
for(int i=0;i<q;i++){
String[] str3= reader.readLine().split(" ");
int x1 = Integer.valueOf(str3[0]);
int y1 = Integer.valueOf(str3[1]);
int x2 = Integer.valueOf(str3[2]);
int y2 = Integer.valueOf(str3[3]);
int c = Integer.valueOf(str3[4]);
insert(x1,y1,x2,y2,c);
}
//相加
for(int i=1;i<=n;i++){
for(int j =1;j<=m;j++){
B[i][j] = B[i][j]+B[i-1][j]+B[i][j-1]-B[i-1][j-1];
//System.out.print(B[i][j]+" ");
writer.write(B[i][j]+" ");
}
writer.write("\n");
}
writer.flush();
reader.close();
writer.close();
}
}
在acm非常容易超时,使用buff更加好