zoukankan      html  css  js  c++  java
  • HDU 1394:Minimum Inversion Number(线段树区间求和单点更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=1394

    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 #define N 5005
     6 #define lson rt<<1,l,m
     7 #define rson rt<<1|1,m+1,r
     8 struct node
     9 {
    10     int l,r,value;
    11 }tree[N<<2];
    12 int a[N];
    13 /*
    14 求移位后的最小逆序数
    15 Update单点增减
    16 Query区间求和
    17 */
    18 void Build(int rt,int l,int r)
    19 {
    20     tree[rt].l=l;
    21     tree[rt].r=r;
    22     tree[rt].value=0;
    23     if(l==r) return ;
    24     int m=(l+r)>>1;
    25     Build(rt<<1,l,m);
    26     Build(rt<<1|1,m+1,r);
    27 }
    28 
    29 void Update(int rt,int num)
    30 {
    31     if(tree[rt].l==num&&tree[rt].r==num){
    32         tree[rt].value=1;
    33         return ;
    34     }
    35     int m=(tree[rt].l+tree[rt].r)>>1;
    36     if(num<=m) Update(rt<<1,num);
    37     else Update(rt<<1|1,num);
    38     tree[rt].value=tree[rt<<1].value+tree[rt<<1|1].value;
    39 }
    40 
    41 int Query(int rt,int l,int r)
    42 {
    43 /*
    44 画个图就明白了,搜寻的区间为[l,r],m代表当前节点的左儿子和右儿子的分支
    45 如果左儿子有包含该区间的元素,即l<=m,那么就要继续递归搜寻左儿子
    46 如果右儿子有包含该区间的元素,即m<r,那么就要继续递归搜寻右儿子
    47 当当前的节点的区间被搜寻的区间[l,r]覆盖的话,就说明该段区间完全在[l,r]里面
    48 那么返回该节点的值
    49 */
    50     if(l<=tree[rt].l&&tree[rt].r<=r){
    51         return tree[rt].value;
    52     }
    53     else{
    54         int m=(tree[rt].l+tree[rt].r)>>1;
    55         int s1=0,s2=0;
    56         if(l<=m) s1=Query(rt<<1,l,r);
    57         if(r>m) s2=Query(rt<<1|1,l,r);
    58         return s1+s2;
    59     }
    60 }
    61 
    62 int main()
    63 {
    64     int n;
    65     while(~scanf("%d",&n)){
    66         Build(1,1,n);
    67         int sum=0;
    68         for(int i=0;i<n;i++){
    69             scanf("%d",&a[i]);
    70             a[i]++;
    71             sum+=Query(1,a[i]+1,n);
    72             Update(1,a[i]);
    73         }
    74         int res = sum;
    75         for(int i=n-1;i>=0;i--){
    76             sum=sum-(n-a[i])+(a[i]-1);
    77             if(sum<res) res=sum;
    78         }
    79         printf("%d
    ",res);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    基于session做的权限控制
    spring有关jar包的作用
    Failed to apply plugin [id 'com.android.application'] 和 Could not find com.android.tools.build:gradle:2.XX的最正确的解决方法
    Android Handler机制(四)---Handler源码解析
    System.currentTimeMillis()与SystemClock.uptimeMillis()
    【转】博客美化(6)为你的博文自动添加目录
    Android Handler机制(三)----Looper源码解析
    Android Handler机制(二)---MessageQueue源码解析
    Android Handler机制(一)---Message源码分析
    关于Android Force Close 出现的原因 以及解决方法
  • 原文地址:https://www.cnblogs.com/fightfordream/p/5656675.html
Copyright © 2011-2022 走看看