import java.util.Scanner;
public class Main{
static int N = 100010;
static int[] q = new int[N];
static int[] temp = new int[N];
public static void merge_sort(int[] q,int l,int r){
if(l >= r) return ;
int mid = (l + r)/2;
merge_sort(q,l,mid);
merge_sort(q,mid + 1, r);
int i = l, j = mid + 1;
int k = 0;
while(i <= mid && j <= r){
if(q[i] < q[j]) temp[k++] = q[i++];
else temp[k++] = q[j++];
}
while(i <= mid) temp[k++] = q[i++];
while(j <= r) temp[k++] = q[j++];
for(i = l,j = 0; i <= r;i++,j++)
q[i] = temp[j];
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for(int i = 0; i < n; i++) q[i] = sc.nextInt();
merge_sort(q,0,n - 1);
for(int i = 0; i < n; i++) System.out.printf("%d ",q[i]);
}
}
差分: 差分其实是前缀和的逆运算,我们知道假设一个数组:a[0]、a[1]、....a[n],那它们的前缀和为s[0]、s[1]、...s[n],至于怎么求,我就不细讲了。
那现在我们还是有这么一个已知的数组a[0]、a[1]、....a[n],那么我们就要构造出一个b[0]、b[1]、...b[n],它们是数组a的差分,同时数组a是数组b的前缀和。
至于为什么,首先要知道数组b是怎么算出来的
所以就是这么构造出来的,有人会觉得很神奇,但确实这么神奇,但这个差分有什么用呢,更详细的说为什么要用差分,这种一种是用来算某个区间要同时加上某个数,如果单纯用循环来加的话,时间复杂度为O(n),但如果是差分,则O(1)的复杂度就可以解决。
核心代码:
public static void insert(int l,int r,int c){
b[l] +=c;
b[r + 1] -=c;
}
为什么是这样子呢,这里我们可以验证一下,首先是b[l]+=c,这里l区间加c,然后我们知道a[n]是数组b的前n项和,从a[l]开始,它一定会包含b[l],为什么呢,我们可以看看
完整代码
import java.util.Scanner;
public class Main{
static int N = 100010;
static int[] a = new int[N];
static int[] b = new int[N];
public static void insert(int l,int r,int c){
b[l] += c;
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();
//同理,我们可以将输入的数拆成差分的形式,给数组b
insert(i,i,a[i]);
}
while(m -- > 0){
int l = sc.nextInt();
int r = sc.nextInt();
int c = sc.nextInt();
insert(l,r,c);
}
for(int i = 1; i <= n; i++){
//算出前缀和,实际上就是求出数组a,只不过省略罢了
b[i] += b[i - 1];
System.out.printf("%d ",b[i]);
}
}
}
二维差分
import java.util.Scanner;
public class Main{
static int N = 1010;
static int[][] a = new int[N][N];
static int[][] b = new int[N][N];
public static void insert(int x1,int y1,int x2,int y2,int c){
b[x1][y1] +=c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int q = sc.nextInt();
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
a[i][j] = sc.nextInt();
insert(i,j,i,j,a[i][j]);
}
}
while(q-- > 0){
int x1 = sc.nextInt();
int y1 = sc.nextInt();
int x2 = sc.nextInt();
int y2 = sc.nextInt();
int c = sc.nextInt();
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 - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
System.out.printf("%d ",b[i][j]);
}
System.out.println();
}
}
}
import java.io.*;
public class Main{
static int N = 1010;
static int[][] a = new int[N][N];
static int[][] b = new int[N][N];
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void insert(int x1,int y1,int x2,int y2,int c){
b[x1][y1] += c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y1] -= c;
b[x2 + 1][y2 + 1] += c;
}
public static void main(String[] args) throws IOException{
String[] str = br.readLine().split(" ");
int n = Integer.parseInt(str[0]);
int m = Integer.parseInt(str[1]);
int q = Integer.parseInt(str[2]);
for(int i = 1; i <= n; i++){
str = br.readLine().split(" ");
for(int j = 1; j <= m; j++){
a[i][j] = Integer.parseInt(str[j - 1]);
insert(i,j,i,j,a[i][j]);
}
}
while(q -- > 0){
str = br.readLine().split(" ");
int x1 = Integer.parseInt(str[0]);
int y1 = Integer.parseInt(str[1]);
int x2 = Integer.parseInt(str[2]);
int y2 = Integer.parseInt(str[3]);
int c = Integer.parseInt(str[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 - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
bw.write(b[i][j] + " ");
}
bw.write("\n");
}
br.close();
bw.flush();
bw.close();
}
}
\