求最小交换次数
- 相邻交换
- 任意交换
相邻交换:(求逆序对数)
- 归并排序
void msort(vector<int> &a, int l, int r) {
if (l == r) {
return;
}
int m = (l + r) >> 1;
msort(a, l, m);
msort(a, m + 1, r);
tmp.clear();
for (int i = l, j = m + 1; i <= m || j <= r;) {
if (i <= m && j <= r) {
if (a[i] <= a[j]) {
tmp.push_back(a[i]);
i++;
} else {
tmp.push_back(a[j]);
j++;
res += (m - i + 1);
}
} else if (i <= m) {
tmp.push_back(a[i]);
i++;
} else {
tmp.push_back(a[j]);
j++;
}
}
for (int i = 0; i < tmp.size(); i++) {
a[l + i] = tmp[i];
}
}
- 树状数组
#include<bits/stdc++.h>
#define M 500005
using namespace std;
int a[M],d[M],t[M],n;
int lowbit(int x)
{
return x&-x;
}
int add(int x)
{
while(x<=n)
{
t[x]++;
x+=lowbit(x);
}
}
int sum(int x)
{
int res=0;
while(x>=1)
{
res+=t[x];
x-=lowbit(x);
}
return res;
}
bool cmp(int x,int y)
{
if(a[x]==a[y]) return x>y;
return a[x]>a[y];
}
int main()
{
long long ans=0;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i],d[i]=i;
sort(d+1,d+n+1,cmp);
for(int i=1;i<=n;i++)
{
add(d[i]);
ans+=sum(d[i]-1);
}
cout<<ans;
return 0;
}
任意交换:(求置换环数)
int judge(vector<int> &a) {
int n = a.size();
vector<int> b = a;
sort(b.begin(), b.end());
for (int i = 0; i < n; i++) {
a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin();
}
int res = n;
vector<bool> vis(n);
for (int i = 0; i < n; i++) {
if (vis[i]) continue;
int j = i;
while (!vis[j]) {
vis[j] = 1;
j = a[j];
}
res--;
}
return res;
}