ACM Minimum Inversion Number 解题报告 -线段树

C - Minimum Inversion Number

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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 //线段树专题解题。
2 //其实一开始没想通,后来手动模拟了一下整个树建立的过程就全部清楚了。
3 //详细AC代码在下面: 

 1 #include"iostream"
 2 #include"algorithm"
 3 #include"cstdio"
 4 #include"cstring"
 5 #include"cmath"
 6 #define max(a,b) a>b?a:b
 7 #define min(a,b) a<b?a:b
 8 #define lson l,m,rt<<1
 9 #define rson m+1,r,rt<<1|1
10 using namespace std;
11 const int MX = 200000+10;
12 int sum[MX<<2];
13 void PushUp(int rt) {
14     sum[rt]=sum[rt<<1]+sum[rt<<1|1];  //更新节点  父节点为子节点之和
15 }
16
17 void Build(int l,int r,int rt) {
18     sum[rt]=0;            //建立一棵空树  【这里之前放在了判断里面,叶节点确实清空了,枝节点漏掉了】
19     if(r==l) return ;
20     int    m=(r+l)>>1;
21     Build(lson);//建立左节点
22     Build(rson);//建立右节点
23 }
24
25 void UpData(int p,int l,int r,int rt) {
26     if(r==l) {            //找到并更新目标点
27         sum[rt]++;
28         return ;
29     }
30     int m=(r+l)>>1;
31     if(p<=m) UpData(p,lson);  //如果不是目标点向左右寻找
32     if(p >m) UpData(p,rson);
33     PushUp(rt);//将更新过的每个点的子节点的和更新。
34 }
35
36 int Query(int L,int R,int l,int r,int rt) {
37     if(L<=l&&R>=r)         //大小超过整个范围
38         return sum[rt];  //返回总数
39     int m=(r+l)>>1;
40     int ret=0;
41     if(L<= m) ret += Query(L,R,lson);  //比x[i]大的树的左值和
42     if(R > m) ret += Query(L,R,rson);  //比x[i]大的树的右值和
43     return ret;
44 }
45 int x[MX];
46 int main() {
47     int n;
48     int sums;
49     char s[2];
50     while(~scanf("%d",&n)) {
51         sums=0;
52         Build(0,n-1,1);         //【这里应该从0~n-1比较好,从1~n的话0的位置不好放在哪里了。后面也就一样了。】
53         for(int i=0; i<n; i++) {
54             scanf("%d",&x[i]);
55             sums+=Query(x[i],n-1,0,n-1,1);
56             UpData(x[i],0,n-1,1);
57         }
58         int ret=sums;
59         for(int i=0; i<n; i++) {
60             sums=sums+n-2*x[i]-1;
61             ret=min(ret,sums);
62         }
63         printf("%d\n",ret);
64     }
65     return 0;
66 }

时间: 2024-10-06 17:06:23

ACM Minimum Inversion Number 解题报告 -线段树的相关文章

HDU 1394 Minimum Inversion Number (数据结构-线段树)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9514    Accepted Submission(s): 5860 Problem Description The inversion number of a given number sequence a1, a2, ..., an

HDU 1394 &lt;Minimum Inversion Number&gt; &lt;逆序数&gt;&lt;线段树&gt;

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 seq

ACM: Just a Hook 解题报告 -线段树

E - Just a Hook Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive met

ACM: 敌兵布阵 解题报告 -线段树

敌兵布阵 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Lily 特别喜欢养花,但是由于她的花特别多,所以照料这些花就变得不太容易.她把她的花依次排成一行,每盆花都有一个美观值.如果Lily把某盆花照料的好的话,这盆花的美观值就会上升,如果照料的不好的话,这盆花的美观值就会下降.有时,Lily想知道某段连续的花的美观值之和是多少,但是,Lily的算术不是很好,你能快

ACM: I Hate It 解题报告 - 线段树

I Hate It Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input 本题目包含多组测试,请处理到文件结束. 在每个测

ACM: Billboard 解题报告-线段树

Billboard Time Limit:8000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在学校的入口处有一个巨大的矩形广告牌,高为h,宽为w.所有种类的广告都可以贴,比如ACM的广告啊,还有餐厅新出了哪些好吃的,等等.. 在9月1号这天,广告牌是空的,之后广告会被一条一条的依次贴上去. 每张广告都是高度为1宽度为wi的细长的矩形纸条. 贴广告的人总是会优先选择最上面的位置来帖,而且在所有

ACM: Hotel 解题报告 - 线段树-区间合并

Hotel Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever th

HDU - 1394 - Minimum Inversion Number (线段树 - 单点更新,区间求和)

题目传送:Minimum Inversion Number 思路:线段树,求最小逆序数,先可以通过n*logn的时间用线段树求出初始的逆序对数,然后递推求出其他的解,递推过程看代码 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include &

HDU 1394 Minimum Inversion Number(线段树求逆序对)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1394 解题报告:给出一个序列,求出这个序列的逆序数,然后依次将第一个数移动到最后一位,求在这个过程中,逆序数最小的序列的逆序数是多少? 这题有一个好处是输入的序列保证是0 到 n-1,所以不许要离散化,还有一个好处就是在计算在这个序列中比每个数大和小的数一共有多少个的时候可以在O(1)时间计算出来,一开始我没有意识到,还傻傻的用了两层for循环来每次都计算,当然这样果断TLE了.把一个数从第一个移