zoukankan      html  css  js  c++  java
  • HDU1394-Minimum Inversion Number

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

                      Minimum Inversion Number

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8205    Accepted Submission(s): 5041

    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
    #include<stdio.h>
    #define maxn 500004  
    struct node  
    {  
        int left,right;  
        int sum;  
    };  
    int val[maxn];
    int n;
    node tree[3*maxn];  
    void build(int left,int right,int i)  
    {  
        tree[i].left =left;  
        tree[i].right =right;  
        tree[i].sum =0;  
        if(tree[i].left ==tree[i].right )  
            return ;  
        build(left,(left+right)/2,2*i);  
        build((left+right)/2+1,right,2*i+1);  
    }  
    void update(int r,int j)
    {
        tree[r].sum++;
        if(tree[r].left==tree[r].right)
            return ;
    int mid=(tree[r].left +tree[r].right )/2;
          if(j<=mid)
              update(r*2,j);
          if(j>mid)
              update(r*2+1,j);
    }
    int getsum(int p, int left, int right)  
    {  
        if (left > right)  
            return 0;  
        if (tree[p].left == left && tree[p].right == right)  
            return tree[p].sum;  
        int m = (tree[p].left + tree[p].right) / 2;  
        if (right <= m)  
            return getsum(p*2, left, right);  
        else if (left > m)  
            return getsum(p*2+1, left, right);  
        else return getsum(p*2, left, m) + getsum(p*2+1, m + 1, right);  
    }  
    int main()  
    {  
        while (~scanf("%d",&n))  
        {  
            build(0,n - 1,1);  
            int i,sum =0,ans;  
            for (i = 1;i<= n; i++)  
            {  
                scanf("%d", &val[i]);  
                sum += getsum(1, val[i], n - 1);  
                update(1, val[i]);  
            }  
            ans = sum;  
            for (i = 1; i <= n; i++)  
            {  
                sum = sum + (n - val[i] - 1) - val[i];  
                ans = sum < ans ? sum : ans;  
            }  
            printf("%d
    ", ans);  
        }  
        return 0;  
    }  
     
  • 相关阅读:
    网站代码优化总结
    移动端 H5 页面注意事项
    js基础知识点收集
    2017-3-26 webpack入门(一)
    gulp教程
    less的使用
    微信小程序接口封装
    div上下左右居中几种方式
    前端知识点-面试
    call和apply
  • 原文地址:https://www.cnblogs.com/cancangood/p/3397530.html
Copyright © 2011-2022 走看看