zoukankan      html  css  js  c++  java
  • Ultra-QuickSort (树状数组求逆序数)

    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
    

    思路:
    假如给的数在1-N范围内,那么我们可以建立一个大小为N+1(避开0)的树状数组,把这列数倒着加入数组,则每次加入一个数的时候我们就可以知道他前面的数(比他小的)有多少个(求区间和),也就是知道了这个数与前面的逆序数,那么每个数与前面数的逆序数之和即为我们要的结果。
    但这个题中单个数的大小范围是0到999999999,直接建数组肯定是不可能的,那么我们可以离散化数据,按数的读入顺序标号,则经过排序后数的逆序就转化为了1-N的一列数的逆序数。
    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    int tree[500005];
    int N;
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    void add(int index,int value)
    {
        for(int i=index ; i<=N ; i+=lowbit(i))
        {
            tree[i] += value;
        }
    }
    
    int getSum(int index)
    {
        int sum = 0;
        for(int i=index ; i>0 ; i-=lowbit(i))
        {
            sum += tree[i];
        }
        return sum;
    }
    
    struct Node
    {
        int Value;
        int Num;
        bool const operator<(const struct Node& a)const  
        {  
            return Value<a.Value;  
        }  
    }board[500005];
    
    int main(void)
    {
        while(scanf("%d",&N)&&N)
        {
            memset(tree,0,sizeof(tree));
            for(int i=1 ; i<=N ; i++)
            {
                scanf("%d",&board[i].Value);
                board[i].Num = i;
            }
            sort(board+1,board+N+1);
            long long sum = 0;
            for(int i=N ; i>0 ; i--)
            {
                sum += getSum(board[i].Num);
                add(board[i].Num,1);
            }
            printf("%lld
    ",sum);
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    NopCommerce代码结构
    至于你信不信,我反正是信了——以类为单位的编程思想
    男人的小金库藏在哪里?——公共数据集Model
    老婆使用说明书——注册系统的逻辑与结构
    ASP.NET学习参考站点
    学了N年英语,你学会翻译了吗?——最基本的数据库连接
    编程也讲禅,您读过《金刚经》吗?——ADO.NET核心类的灭度与SQLHelper的诞生——十八相送(上)
    文件夹病毒专杀工具
    不想当将军的学生,不是好程序员——数据访问层DAL——程序结构的思考
    html的标签一共有多少个?
  • 原文地址:https://www.cnblogs.com/vocaloid01/p/9514176.html
Copyright © 2011-2022 走看看