题目【逆序对应用】
思路
- 首先,什么状态是目标状态
- 即(ai-bi)^2 最小的状态=ai^2+bi^2-2aibi
- ai^2与bi^2不变, 主要要求sum(aibi)最大
- 可以证明,第二列的大小顺序与第一列保持一致最大 即aibi差距最小最大
- 令x[sx[i]] = sx[i]
- x的逆序对即为需要交换的次数
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
const int mod = 1e8-3;
int res=0;
struct Node {
int v,id;
bool operator<(const Node& t) const {
return v<t.v;
}
}a[N], b[N];
int x[N];
int tmp[N];
void msort(int l, int r) // 归并排序
{
if(l >= r) return;
int mid = l+r>>1;
msort(l,mid), msort(mid+1, r);
//合并两个有序数组
int i=l, j=mid+1, k=0;
while(i<=mid && j<=r) {
if(x[i]<=x[j]) {
tmp[k++] = x[i++];
}else {
res = (res + mid-i+1)%mod;
tmp[k++] = x[j++];
}
}
while(i<=mid) tmp[k++] = x[i++];
while(j<=r) tmp[k++] = x[j++];
for(int i=l; i<=r; ++i) x[i] = tmp[i-l];//还是[l,r]好
}
int n;
int main()
{
cin>>n;
for(int i=1; i<=n; ++i) {
scanf("%d", &a[i].v);
a[i].id = i;
}
for(int i=1; i<=n; ++i) {
scanf("%d", &b[i].v);
b[i].id = i;
}
sort(a+1,a+n+1);
sort(b+1,b+n+1);
for(int i=1; i<=n; ++i) {
x[a[i].id] = b[i].id;
}
msort(1,n);
cout<<res;
return 0;
}