这道题先求出整个数列(长度为n)的逆序对个数,方法是对于数m,累加线段树中(m, n-1)中已插入数的个数,再更新…..求出的逆序对个数为sum.在循环数列,把每个数调到最后面,假设数为M,则此时sum += n-1-2*m;
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define maxn 5005
struct node{
int l, r, s;
}T[maxn<<2];
int num[maxn];
void Build(int n, int l, int r)
{
T[n].l = l;
T[n].r = r;
T[n].s = 0;
if(l == r)
return ;
int mid = (l + r) / 2;
Build(n<<1, l, mid);
Build(n<<1|1, mid+1, r);
}
void Update(int n, int s)
{
if(T[n].l == T[n].r)
{
T[n].s++;
return ;
}
int mid = (T[n].l + T[n].r) / 2;
if(s <= mid)
Update(n<<1, s);
else
Update(n<<1|1, s);
T[n].s = T[n<<1].s + T[n<<1|1].s;
}
void Query(int n, int l, int r, int &s)
{
if(T[n].l == l && T[n].r == r)
{
s += T[n].s;
return ;
}
int mid = (T[n].l + T[n].r) / 2;
if(r <= mid)
Query(n<<1, l, r, s);
else if(l > mid)
Query(n<<1|1, l, r, s);
else{
Query(n<<1, l, mid, s);
Query(n<<1|1, mid+1, r, s);
}
}
int main()
{
//freopen("in.txt", "r", stdin);
int n;
while(cin >> n)
{
int sum = 0;
Build(1, 0, n-1);
for(int i = 0; i < n; i++)
{
int b;
scanf("%d", num+i);
b = 0;
Query(1, num[i], n-1, b);
sum += b;
Update(1, num[i]);
}
int mins = sum;
for(int i = 0; i < n-1; i++)
{
int m = n - 1 - 2 * num[i];
sum += m;
mins = min(mins, sum);
}
cout << mins << endl;
}
return 0;
}