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.
InputThe 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.
OutputFor each case, output the minimum inversion number on a single line.
Sample Input
10 1 3 6 9 0 8 5 7 4 2
Sample Output
16
解题思路:
线段树各个结点记录m——n之间有多少个数已经出现。
1 #include <iostream> 2 #include <queue> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 typedef long long ll; 8 typedef unsigned long long ull; 9 struct node 10 { 11 int left,right,mid; 12 int num; 13 }st[50005]; 14 void init(int l,int r,int n) 15 { 16 st[n].left=l; 17 st[n].right=r; 18 st[n].mid=(l+r)/2; 19 st[n].num=0; 20 if(l+1==r) 21 return; 22 init(l,(l+r)/2,2*n); 23 init((l+r)/2,r,2*n+1); 24 } 25 void update(int pri,int n) 26 { 27 st[n].num++; 28 if(st[n].left+1==st[n].right) 29 return; 30 if(pri>=st[n].mid) 31 update(pri,2*n+1); 32 else 33 update(pri,2*n); 34 } 35 int query(int pri,int n) 36 { 37 if(st[n].left+1==st[n].right) 38 return st[n].num; 39 if(pri>=st[n].mid) 40 return query(pri,2*n)+query(pri,2*n+1); 41 else 42 return query(pri,2*n); 43 44 } 45 int n; 46 int tem; 47 int an=0; 48 int ans=0; 49 int x[5005]; 50 int main() 51 { 52 while(~scanf("%d",&n)) 53 { 54 an=0; 55 init(1,n+1,1); 56 int i; 57 for(i=1;i<=n;i++) 58 { 59 scanf("%d",&tem); 60 x[i]=n-tem; 61 an+=query(n-tem,1); 62 update(n-tem,1); 63 // an+=query(tem+1,1); 64 // update(tem+1,1); 65 // printf("i=%d an=%d\n",i,an); 66 } 67 ans=an; 68 for(i=1;i<=n;i++) 69 { 70 ans+=(-n+2*x[i]-1); 71 an=min(ans,an); 72 } 73 printf("%d\n",an); 74 } 75 }
原先的写的好差啊……居然还不T能过……
1 #include <iostream> 2 #include<bits/stdc++.h> 3 #include <stack> 4 #include <queue> 5 #include <map> 6 #include <set> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <math.h> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned long long ull; 14 const int MAX=5e3+5; 15 int a[MAX],sum[MAX<<2]; 16 int n; 17 void update(int lo,int l,int r,int k) 18 { 19 sum[k]++; 20 if(l==r) 21 return; 22 int mid=l+r>>1; 23 if(lo<=mid) 24 update(lo,l,mid,2*k); 25 else 26 update(lo,mid+1,r,2*k+1); 27 } 28 int query(int left,int l,int r,int k) 29 { 30 if(l>=left) 31 return sum[k]; 32 int mid=l+r>>1; 33 if(left>mid) 34 return query(left,mid+1,r,2*k+1); 35 else 36 return query(left,l,mid,2*k)+query(left,mid+1,r,2*k+1); 37 } 38 int an,he; 39 int main() 40 { 41 while(~scanf("%d",&n)) 42 { 43 an=0; 44 for(int i=0;i<=n*4;i++) 45 sum[i]=0; 46 for(int i=1;i<=n;i++) 47 { 48 scanf("%d",&a[i]); 49 update(a[i],0,n-1,1); 50 if(a[i]!=n-1) 51 an+=query(a[i]+1,0,n-1,1); 52 } 53 he=an; 54 for(int i=1;i<n;i++) 55 { 56 he=he+n-1-2*a[i]; 57 an=min(an,he); 58 } 59 printf("%d\n",an); 60 } 61 }