Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15538 Accepted Submission(s): 9479
Problem Description
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.
For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:
a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
a2, a3, ..., an, a1 (where m = 1)
a3, a4, ..., an, a1, a2 (where m = 2)
...
an, a1, a2, ..., an-1 (where m = n-1)
You are asked to write a program to find the minimum inversion number out of the above sequences.
Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
Output
For each case, output the minimum inversion number on a single line.
Sample Input
Sample Output
Author
CHEN, Gaoli
Source
ZOJ Monthly, January 2003
Recommend
Ignatius.L | We have carefully selected several similar problems for you: 1166 1698 1540 1542 1255
树状数组求逆序对。
每次将一个点从最前面移动到最后面,只需要将当前的逆序对数加上比它大的数的个数,再减去比它小的数的个数。
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define LL long long
#define pa pair<int,int>
#define MAXN 5005
#define INF 1000000000
using namespace std;
int a[MAXN],f[MAXN],ans,now,n;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline int getsum(int x)
{
int ret=0;
for(int i=x;i;i-=(-i)&i) ret+=f[i];
return ret;
}
inline void add(int x)
{
for(int i=x;i<=n;i+=(-i)&i) f[i]++;
}
int main()
{
while (~scanf("%d",&n))
{
now=0;
memset(f,0,sizeof(f));
F(i,1,n) a[i]=read()+1;
D(i,n,1){now+=getsum(a[i]-1);add(a[i]);}
ans=now;
F(i,1,n-1) now=now+n+1-a[i]*2,ans=min(ans,now);
printf("%d\n",ans);
}
}