码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1394 Minimum Inversion Number 线段树

时间:2015-10-17 17:33:11      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

 

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 <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn=5010;
 6 int sum[maxn<<2];
 7 void push_up(int rt)
 8 {
 9     sum[rt]=sum[rt<<1]+sum[rt<<1 | 1];
10 }
11 void build(int rt,int first,int end)
12 {
13      sum[rt]=0;
14     if(first==end)
15         return ;
16     int mid=(first+end)>>1;
17     build(rt<<1,first,mid);
18     build(rt<<1 | 1,mid+1,end);
19 }
20 int quary(int rt,int first,int end,int left,int right)
21 {
22     if(left<=first && right>=end)
23         return sum[rt];
24     int mid=(first+end)>>1;
25     int ans=0;
26     if(left<=mid)
27         ans+=quary(rt<<1,first,mid,left,right);
28     if(right>mid)
29         ans+=quary(rt<<1 | 1,mid+1,end,left,right);
30     return ans;
31 }
32 void update(int rt,int first,int end,int a)
33 {
34     if(first==end)
35     {
36         sum[rt]++;
37         return ;
38     }
39     int mid=(first+end)>>1;
40     if(a<=mid)
41         update(rt<<1,first,mid,a);
42     else
43         update(rt<<1 | 1,mid+1,end,a);
44         push_up(rt);
45 }
46 int a[maxn];
47 int main()
48 {
49     int n;
50     while(cin>>n)
51     {
52         build(1,0,n-1);
53         int sum=0;
54         for(int i=0;i<n;i++)
55         {
56              cin>>a[i];
57              sum+=quary(1,0,n-1,a[i],n-1);
58              update(1,0,n-1,a[i]);
59         }
60         int ans=sum;
61         for(int i=0;i<n;i++)
62         {
63             sum+=n-a[i]-a[i]-1;
64             ans=min(ans,sum);
65         }
66         cout<<ans<<endl;
67     }
68     return 0;
69 }
View Code

 

hdu 1394 Minimum Inversion Number 线段树

标签:

原文地址:http://www.cnblogs.com/cxbky/p/4887726.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!