这题树状数组挺好做的,只是转化比较巧妙
可以这样考虑:原来有n个空位,从左到右扫描原序列,扫描到第i个,则a[i]的位置被"占据",
所有1----a[i]的空位数加起来就是原序列的inversion number,用树状数组解决上述问题。第二个序列由原序列得到,第三个序列由第二个变化得到.........原序列得到第二个序列时,即t-a[1]+1+n-a[i],接下来的就简单了
#include<iostream>
using namespace std;
#define N 5005
int c[N],a[N];
int low(int k)
{
return k&(-k);
}
void update(int k,int n)
{
while(k<=n)
{
c[k]++;
k+=low(k);
}
return ;
}
int query(int k)
{
int sum=0;
while(k>0)
{
sum+=c[k];
k-=low(k);
}
return sum;
}
int main()
{
int n,i,minn,t,temp;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d",&temp);
a[i]=++temp;
}
memset(c,0,sizeof(c));
t=0;
for(i=1;i<=n;i++)
{
update(a[i],n);
t+=(a[i]-query(a[i]));
}
minn=t;
for(i=1;i<n;i++)
{
if(t+n-2*a[i]+1<minn)
minn=t+n-2*a[i]+1;
t=t+n-2*a[i]+1;
}
printf("%d/n",minn);
}
return 0;
}