题目链接:https://www.luogu.com.cn/problem/P1966
解题思路:
答案最小则,a的第i小元素和b的第i小元素配。
先将 a、b 离散化成 0~n-1。
然后假设b为有序的情况下a的每个元素是什么,推导出a。
然后对a求逆序对(我这里用归并排序做的)。
示例代码:
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 100000000 - 3;
const int maxn = 100010;
int n, a[maxn], b[maxn], tmp[maxn], pa[maxn];
long long ans;
void merge_sort(int L, int R) {
if (L == R) return;
int mid = (L + R) / 2;
int i = L, j = mid + 1, k = L;
merge_sort(L, mid);
merge_sort(mid+1, R);
while (i <= mid && j <= R) {
if (a[i] < a[j]) {
b[k++] = a[i++];
}
else {
ans += mid - i + 1;
b[k++] = a[j++];
}
}
while (i <= mid) {
b[k++] = a[i++];
}
while (j <= R) {
b[k++] = a[j++];
}
for (i = L; i <= R; i ++) a[i] = b[i];
}
int main() {
cin >> n;
for (int i = 0; i < n; i ++) {
cin >> a[i];
tmp[i] = a[i];
}
sort(tmp, tmp+n);
for (int i = 0; i < n; i ++) a[i] = lower_bound(tmp, tmp+n, a[i]) - tmp;
for (int i = 0; i < n; i ++) {
cin >> b[i];
tmp[i] = b[i];
}
sort(tmp, tmp+n);
for (int i = 0; i < n; i ++) b[i] = lower_bound(tmp, tmp+n, b[i]) - tmp;
for (int i = 0; i < n; i ++) pa[a[i]] = i;
for (int i = 0; i < n; i ++) {
int j = pa[b[i]];
a[j] = i;
}
merge_sort(0, n-1);
ans %= MOD;
cout << ans << endl;
return 0;
}