Minimum Inversion Number(线段树求逆序数)
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 15517 Accepted Submission(s): 9467
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.
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
10
1 3 6 9 0 8 5 7 4 2
mergesort
Sample Output
16
Author
CHEN, Gaoli
题解:线段树;也可以用归并排序,也可以用树状数组;注意每次把第一个放在最后这个条件;归并:http://www.cnblogs.com/handsomecui/p/4814442.html
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<vector> #include<map> using namespace std; const int MAXN=5010; #define lson root<<1,l,mid #define rson root<<1|1,mid+1,r #define pushup tree[root]=tree[root<<1]+tree[root<<1|1] #define mem(x,y) memset(x,y,sizeof(x)) int tree[MAXN<<2]; int a[MAXN]; int ans; void update(int v,int root,int l,int r){ int mid=(l+r)>>1; if(l==v&&r==v){ tree[root]++; return; } if(mid>=v)update(v,lson); if(mid<v)update(v,rson); pushup; } void query(int L,int R,int root,int l,int r){ int mid=(l+r)>>1; if(l>=L&&r<=R){ ans+=tree[root]; return; } if(mid>=L)query(L,R,lson); if(mid<R)query(L,R,rson); } int main(){ int N; while(~scanf("%d",&N)){ mem(tree,0); ans=0; int x; for(int i=0;i<N;i++){ scanf("%d",&x);a[i]=x; query(x+1,N-1,1,0,N-1); // printf("%d\n",ans); update(x,1,0,N-1); } int cnt=ans; for(int i=0;i<N;i++){ cnt=cnt+N-1-a[i]-a[i]; ans=min(ans,cnt); } printf("%d\n",ans); } return 0; }