题目链接
题意:
给你两个数组,相邻两个数字之间可以互换位置,求交换位置至少多少次后可以使得∑(ai-b)^2最小。
思路:
离散化a[i]与b[i]数组后开一个c[i]数组令c[a[i]]=b[i],求c[i]数组的逆序对个数即可。
代码:
树状数组代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=1e5+5;
const int inf=0x3f3f3f3f;
const int mod=99999997;
int n,arr[N],brr[N],crr[N],flag[N],num=0;
struct Sum
{
int a,loc;
}t[N];
int cmp(Sum a,Sum b)
{
return a.a<b.a;
}
int lowbit(int k)
{
return k&(-k);
}
int update(int p)
{
while(p<=n)
{
flag[p]+=1;
p+=lowbit(p);
}
}
int getsum(int p)
{
int res=0;
while(p)
{
res+=flag[p];
p-=lowbit(p);
}
return res;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>arr[i];
t[i].a=arr[i];
t[i].loc=i;
}
sort(t+1,t+n+1,cmp);
for(int i=1;i<=n;i++)
{
arr[t[i].loc]=i;
}
for(int i=1;i<=n;i++)
{
cin>>brr[i];
t[i].a=brr[i];
t[i].loc=i;
}
sort(t+1,t+n+1,cmp);
for(int i=1;i<=n;i++)
{
brr[t[i].loc]=i;
}
for(int i=1;i<=n;i++)
{
crr[arr[i]]=brr[i];
}
for(int i=1;i<=n;i++)
{
update(crr[i]);
num+=i-getsum(crr[i]);
num%=mod;
}
cout<<num<<endl;
return 0;
}
归并排序代码:
hhh我不会