import java.io.*;
class Read {
StreamTokenizer st;
public Read() {
st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
}
public int nextInt() throws IOException {
st.nextToken();
return (int)st.nval;
}
public String next() throws IOException {
st.nextToken();
return st.sval;
}
}
public class Main {
public static void main(String[] args) throws IOException {
Read sc = new Read();
int n = sc.nextInt();
int[] q = new int[n];
for (int i = 0; i < n; i++) {
q[i] = sc.nextInt();
}
System.out.println(merge_sort(q, 0, n - 1));
}
public static long merge_sort(int[] q, int l, int r) {
if (l >= r) return0;
int mid = l + r >> 1;
long res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
for (int i = l, j = mid + 1; i <= mid; i++) {
while (j <= r && q[i] > q[j]) j++;
res += j - (mid + 1L);
}
int i = l, j = mid + 1, k = 0;
int[] tmp = new int[r - l + 1];
while (i <= mid && j <= r) {
if (q[i] <= q[j]) tmp[k++] = q[i++];
else tmp[k++] = q[j++];
}
while (i <= mid) tmp[k++] = q[i++];
while (j <= r) tmp[k++] = q[j++];
for (i = l, j = 0; i <= r; i++, j++) {
q[i] = tmp[j];
}
return res;
}
}
对于 5 6 1,如果采用
res += j - mid
,当 5 6 和 1 合并时,只会把 <5, 1> 算上,<6, 1>加不上了采用
res += j - mid
时,想要让6对结果产生贡献,需要确保6能参与到比较当中,比如 4 6 1 5 ,4 6 和 1 5 合并简单来说,就是
res += j - mid
有些情况下会算不全牛逼,谢谢大佬👍🏻👍🏻👍🏻
大佬,我想到了一种可以解决这个问题的方法了
import java.io.*; class Read { StreamTokenizer st; public Read() { st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); } public int nextInt() throws IOException { st.nextToken(); return (int)st.nval; } public String next() throws IOException { st.nextToken(); return st.sval; } } public class Main { public static void main(String[] args) throws IOException { Read sc = new Read(); int n = sc.nextInt(); int[] q = new int[n]; for (int i = 0; i < n; i++) { q[i] = sc.nextInt(); } System.out.println(merge_sort(q, 0, n - 1)); } public static long merge_sort(int[] q, int l, int r) { if (l >= r) return 0; int mid = l + r >> 1; long res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r); for (int i = l, j = mid + 1; i <= mid; i++) { while (j <= r && q[i] > q[j]) j++; res += j - (mid + 1L); } int i = l, j = mid + 1, k = 0; int[] tmp = new int[r - l + 1]; while (i <= mid && j <= r) { if (q[i] <= q[j]) tmp[k++] = q[i++]; else tmp[k++] = q[j++]; } while (i <= mid) tmp[k++] = q[i++]; while (j <= r) tmp[k++] = q[j++]; for (i = l, j = 0; i <= r; i++, j++) { q[i] = tmp[j]; } return res; } }