题意:https://www.luogu.com.cn/problem/AT_abc261_f
思路:首先一个不带颜色的数组变成有序的最小次数为该数组逆序对数,那么带上颜色也就是对于同一种颜色里面的逆序部分可以减少次数。所以答案就是原数组逆序对减去每个颜色数组的逆序对,每次弄完一种颜色后还原即可无需二维。
/*keep on going and never give up*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
typedef pair<int, int> pii;
#define int long long
#define lowbit(x) x&(-x)
#define endl '\n'
#define wk is zqx ta die
pii pl[300005];
int f[300005];
int n;
void add(int x, int y) {
while (x <= n) {
f[x] += y;
x += lowbit(x);
}
}
int query(int l) {
int res = 0;
while (l) {
res += f[l];
l -= lowbit(l);
}
return res;
}
vector<int> col[300005];
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
int ans = 0;
for (int i = 1; i <= n; i++) {
cin >> pl[i].first;
}
for (int i = 1; i <= n; i++) {
cin >> pl[i].second;
col[pl[i].first].push_back(pl[i].second);
ans += query(n) - query(pl[i].second);
add(pl[i].second, 1);
}
for (int i = 1; i <= n; i++) {
f[i] = 0;
}
for (int i = 1; i <= n; i++) {
if (col[i].size() == 0) {
continue;
}
for (int j = 0; j < col[i].size(); j++) {
ans -= query(n) - query(col[i][j]);
add(col[i][j], 1);
}
for (int j = 0; j < col[i].size(); j++) {
add(col[i][j], -1);
}
}
cout << ans << endl;
return 0;
}