zoukankan      html  css  js  c++  java
  • HDU Problem 1394 Minimum Inversion Number【树状数组】

    Minimum Inversion Number

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

    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
     
    Author
    CHEN, Gaoli
     
    Source
     
    Recommend
    Ignatius.L   |   We have carefully selected several similar problems for you:  1698 1540 1542 1255 1754 
     

    一开始没有看到数组是连续的。。。。

    先求出最原始的逆序数和ans

    如果数组是连续的那就好办了,对于第一个元素,有a【0】 - 1 个元素是小于它的, 而有n - a【0】‘个元素是大于它的。所以每次转换就变成了

    ans = ans - a【0】+ 1 + n +  - a【0】;

    #include <cstdio>
    #include <set>
    #include <map>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define space " "
    using namespace std;
    const int MAXN = 5000 + 10;
    const int INF = 0x3f3f3f3f;
    int n, ar[MAXN], b[MAXN], num[MAXN];
    int sum(int x) {
        int s = 0;
        while (x >= 1) {
            s += num[x];
            x -= x&-x;
        }
        return s;
    }
    void add(int x, int y) {
        while (x <= n) {
            num[x] += y;
            x += x&-x;
        }
    }
    int main() {
        while (scanf("%d", &n) != EOF) {
            for (int i = 1; i <= n; i++) {
                scanf("%d", &ar[i]); ar[i]++;
            }
            int ans = 0;
            memset(num, 0, sizeof(num));
            for (int i = 1; i <= n; i++) {
                add(ar[i], 1);
                ans += i - sum(ar[i]);
            }
            int minn = ans;
            for (int i = 1; i <= n; i++) {
                ans += n - ar[i] - ar[i] + 1;
                minn = min(minn, ans);
            }
            printf("%d
    ", minn);
        }
        return 0;
    }




  • 相关阅读:
    CIA泄露资料分析(黑客工具&技术)—Windows篇
    包学会之浅入浅出Vue.js:结业篇
    包学会之浅入浅出Vue.js:升学篇
    包学会之浅入浅出Vue.js:开学篇
    Manacher算法详解
    CSP-S 2019 游记
    洛谷 P3373 【模板】线段树 2
    AHOI 2009 维护序列
    洛谷 P4017 最大食物链计数
    洛谷 SP14932 LCA
  • 原文地址:https://www.cnblogs.com/cniwoq/p/6770814.html
Copyright © 2011-2022 走看看