HDU 1394 Minimum Inversion Number

Minimum Inversion Number




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
10
1 3 6 9 0 8 5 7 4 2
 

 

Sample Output
16
 
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 struct segtree
 7 {
 8     int l,r;
 9     int num;
10     int mid()
11     {
12         return (l+r)>>1;
13     }
14 };
15 
16 segtree tree[5005<<2];
17 int a[5005<<2];
18 
19 void PushUp(int rt)
20 {
21     tree[rt].num=tree[rt<<1].num+tree[rt<<1|1].num;
22 }
23 
24 void build(int l,int r,int rt)
25 {
26     tree[rt].l=l;
27     tree[rt].r=r;
28     tree[rt].num=0;
29     if(l==r)return;
30     int m=tree[rt].mid();
31     build(l,m,rt<<1);
32     build(m+1,r,rt<<1|1);
33 }
34 
35 int query(int l,int r,int rt)
36 {
37     if(tree[rt].l==l&&tree[rt].r==r)
38         return tree[rt].num;
39     int m=tree[rt].mid();
40     if(r<=m)
41         return query(l,r,rt<<1);
42     else if(l>m)
43         return query(l,r,rt<<1|1);
44     else
45         return query(l,m,rt<<1)+query(m+1,r,rt<<1|1);
46 }
47 
48 void update(int pos,int rt)
49 {
50     if(tree[rt].l==tree[rt].r)
51     {
52         tree[rt].num++;
53         return;
54     }
55     int m=tree[rt].mid();
56     if(pos<=m)update(pos,rt<<1);
57     else update(pos,rt<<1|1);
58     PushUp(rt);
59 }
60 
61 int main()
62 {
63     int n,i,j;
64     while(scanf("%d",&n)!=EOF)
65     {
66         for(i=0;i<n;i++)
67             scanf("%d",&a[i]);
68         build(0,n-1,1);
69         int sum=0;
70         for(i=0;i<n;i++)
71         {
72             sum+=query(a[i],n-1,1);
73             update(a[i],1);
74         }
75         int ans=999999999;
76         ans=min(ans,sum);
77         for(i=0;i<n;i++)
78         {
79             sum=sum-a[i]+n-1-a[i];
80             ans=min(ans,sum);
81         }
82         printf("%d\n",ans);
83     }
84     return 0;
85 }

 

posted on 2015-08-09 16:44    阅读(149)  评论(0编辑  收藏  举报

导航