思路
我们首先把\(a,b\)输入进一个数据结构,并且对这两个序列以高度为关键字排序。我们先来写出一组样例排序后的样子(数组下标为原本的位置):\[\{1_3,2_1,3_2,4_4\}\]与\[\{1_3,2_2,3_1,4_4\}\]我们观察发现,显然我们可以进行离散处理。所以令\(mapping[]\)为离散数组,在两组排序后进行\(mapping[a[i].index] = b[i].index\),便可以完成离散化。问题便转换为b数组要完成多少次变换才能与a相同(因为我们已经进行了离散化处理,\(mapping[]\)便可以在\(n\)范围内)。我们可以想到使用计算逆序对个数来解决这个问题。问题迎刃而解。
代码
// P1966.cpp
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1000200;
const int mod = 99999997;
#define ll long long
struct element
{
int val, idx;
bool operator<(const element &ele) const
{
return val < ele.val;
}
} a[maxn], b[maxn];
int mapping[maxn], tmp[maxn], n;
int ans = 0;
void merge(int l, int mid, int r)
{
int sa = l;
int p = mid + 1;
int bias = l;
while (sa <= mid && p <= r)
if (mapping[sa] < mapping[p])
tmp[bias++] = mapping[sa++];
else
tmp[bias++] = mapping[p++], ans += (mid - sa + 1), ans %= mod;
while (sa <= mid)
tmp[bias++] = mapping[sa++];
while (p <= r)
tmp[bias++] = mapping[p++];
for (int i = l; i <= r; i++)
mapping[i] = tmp[i];
}
void mergeSort(int l, int r)
{
if (l == r)
return;
int mid = (l + r) >> 1;
mergeSort(l, mid);
mergeSort(mid + 1, r);
merge(l, mid, r);
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i].val), a[i].idx = i;
for (int i = 1; i <= n; i++)
scanf("%d", &b[i].val), b[i].idx = i;
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
for (int i = 1; i <= n; i++)
mapping[a[i].idx] = b[i].idx;
mergeSort(1, n);
cout << ans;
return 0;
}
// P1966.cpp
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1000200;
const int mod = 99999997;
#define ll long long
struct element
{
int val, idx;
bool operator<(const element &ele) const
{
return val < ele.val;
}
} a[maxn], b[maxn];
int mapping[maxn], tmp[maxn], n;
int ans = 0;
void merge(int l, int mid, int r)
{
int sa = l;
int p = mid + 1;
int bias = l;
while (sa <= mid && p <= r)
if (mapping[sa] < mapping[p])
tmp[bias++] = mapping[sa++];
else
tmp[bias++] = mapping[p++], ans += (mid - sa + 1), ans %= mod;
while (sa <= mid)
tmp[bias++] = mapping[sa++];
while (p <= r)
tmp[bias++] = mapping[p++];
for (int i = l; i <= r; i++)
mapping[i] = tmp[i];
}
void mergeSort(int l, int r)
{
if (l == r)
return;
int mid = (l + r) >> 1;
mergeSort(l, mid);
mergeSort(mid + 1, r);
merge(l, mid, r);
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i].val), a[i].idx = i;
for (int i = 1; i <= n; i++)
scanf("%d", &b[i].val), b[i].idx = i;
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
for (int i = 1; i <= n; i++)
mapping[a[i].idx] = b[i].idx;
mergeSort(1, n);
cout << ans;
return 0;
}
// P1966.cpp #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1000200; const int mod = 99999997; #define ll long long struct element { int val, idx; bool operator<(const element &ele) const { return val < ele.val; } } a[maxn], b[maxn]; int mapping[maxn], tmp[maxn], n; int ans = 0; void merge(int l, int mid, int r) { int sa = l; int p = mid + 1; int bias = l; while (sa <= mid && p <= r) if (mapping[sa] < mapping[p]) tmp[bias++] = mapping[sa++]; else tmp[bias++] = mapping[p++], ans += (mid - sa + 1), ans %= mod; while (sa <= mid) tmp[bias++] = mapping[sa++]; while (p <= r) tmp[bias++] = mapping[p++]; for (int i = l; i <= r; i++) mapping[i] = tmp[i]; } void mergeSort(int l, int r) { if (l == r) return; int mid = (l + r) >> 1; mergeSort(l, mid); mergeSort(mid + 1, r); merge(l, mid, r); } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i].val), a[i].idx = i; for (int i = 1; i <= n; i++) scanf("%d", &b[i].val), b[i].idx = i; sort(a + 1, a + n + 1); sort(b + 1, b + n + 1); for (int i = 1; i <= n; i++) mapping[a[i].idx] = b[i].idx; mergeSort(1, n); cout << ans; return 0; }