zoukankan      html  css  js  c++  java
  • ZOJ-2386 Ultra-QuickSort 【树状数组求逆序数+离散化】

    Description

    In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence

      9 1 0 5 4 ,

    Ultra-QuickSort produces the output

      0 1 4 5 9 .

    Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.


    Input

    The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 <= a[i] <= 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.


    Output

    For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

    Sample Input

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0


    Sample Output

    6
    0


    题解:

    树状数组求逆序数,先离散化,不然1e9开不下,然后每次对一个数id[i],将树状数组中这个位置+1,统计这个位置的前缀和,然后用i-sum(id[i])(差实际上就是id[i]位置后缀和)就是这个数id[i]导致的逆序对数量。

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define INF 0x3f3f3f3f
     7 #define M(a, b) memset(a, b, sizeof(a))
     8 const int N = 5e5 + 10;
     9 int c[N], id[N], n;
    10 struct node {
    11     int val, pos;
    12     bool operator < (const node &rhs) const {
    13         return val < rhs.val;
    14     }
    15 }a[N];
    16 
    17 int lowbit(int x) {return x & -x;}
    18 
    19 void add(int x, int d) {
    20     while (x <= n) {
    21         c[x] += d;
    22         x += lowbit(x);
    23     }
    24 }
    25 
    26 int sum(int x) {
    27     long long ret = 0;
    28     while (x) {
    29         ret += c[x];
    30         x -= lowbit(x);
    31     }
    32     return ret;
    33 }
    34 
    35 int main() {
    36     while (scanf("%d", &n), n) {
    37         M(c, 0);
    38         for (int i = 1; i <= n; ++i)
    39             scanf("%d", &a[i].val), a[i].pos = i;
    40         sort(a+1, a+1+n);
    41         for (int i = 1; i <= n; ++i) id[a[i].pos] = i;
    42         long long ans = 0;
    43         for (int i = 1; i <= n; ++i) {
    44             add(id[i], 1);
    45             ans += i-sum(id[i]);
    46         }
    47         printf("%lld
    ", ans);
    48     }
    49 
    50     return 0;
    51 }
  • 相关阅读:
    linux配置PHP环境!!(云服务器架设)
    JQ上传预览+存数据库
    AJAX做增删改查详细!
    JS解析XML
    UEditor编辑器的使用
    php注释规范
    phpexcel导出数据表格
    简单分析JavaScript中的面向对象
    制作smarty模版缓存文件
    求二叉树中节点的最大距离
  • 原文地址:https://www.cnblogs.com/robin1998/p/6858923.html
Copyright © 2011-2022 走看看