/*题意描述: 求逆序对
给你一个有0--n-1数字组成的序列,然后进行这样的操作,
每次将最前面一个元素放到最后面去会得到一个序列,那么这样就形成了n个序列,
那么每个序列都有一个逆序数,找出其中最小的一个输出!
*/
#include<stdio.h>
const int maxn=5005;
struct Node
{
int left,right,sum;
}Tree[3*maxn];
int a[maxn];
void build(int left,int right,int pos)
{
Tree[pos].left=left;
Tree[pos].right=right;
if(left==right)
{
Tree[pos].sum=0;
return ;
}
int mid=(left + right)>>1;
build(left,mid,2*pos);
build(mid+1,right,2*pos+1);
Tree[pos].sum=Tree[2*pos].sum+Tree[2*pos+1].sum;
}
int query(int left,int right,int pos)
{
if(Tree[pos].left==left && Tree[pos].right==right)
{
return Tree[pos].sum;
}
int mid=(Tree[pos].left + Tree[pos].right)>>1;
if(right<=mid)
return query(left,right,2*pos);
else if(left>mid)
return query(left,right,2*pos+1);
else
{
return query(left,mid,2*pos) + query(mid+1,right,2*pos+1);
}
//return Tree[pos].sum=(Tree[2*pos].sum+Tree[2*pos+1].sum);
}
/*
void update(int left,int right,int pos)
{
if(left==Tree[pos].left && Tree[pos].right==right)
{
Tree[pos].sum++;
}
int mid=(Tree[pos].left + Tree[pos].right)>>1;
if(right<=mid)
{
update(left,right,2*pos);
}
else if(left>mid)
{
update(left,right,2*pos+1);
}
else
{
update(left,mid,2*pos);
update(mid+1,right,2*pos+1);
}
Tree[pos].sum=Tree[2*pos].sum+Tree[2*pos+1].sum;
}*/
void update(int id,int pos)
{
Tree[pos].sum++;
if(Tree[pos].left==Tree[pos].right)
{
return ;
}
int mid= (Tree[pos].left+ Tree[pos].right)>>1;
if(id<=mid)
update(id,2*pos);
else
update(id,2*pos+1);
}
int main()
{
int n,i;
while(scanf("%d",&n)!=EOF)
{
build(1,n,1);
int count=0;
// printf("*\n");
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
int x=query(a[i]+1,n,1);
count+=x;
printf("%d ",x);
update(a[i],1);
}
// printf("(count)%d\n",count);
int ans=count;
for(i=1;i<=n;i++){
count+=-a[i]+n-1-a[i];
// printf("%d\n",count);
if(ans>count)ans=count;
}
printf("%d\n",ans);
}
return 0;
}