zoukankan      html  css  js  c++  java
  • poj 2299 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

    求逆序对数,具体思路是,在归并的过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数.
    归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

    归并实现:直接套模板

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 int n,a[500005],b[500005];
     5 long long count;
     6 void Merge(int *a,int left,int mid,int right)
     7 {
     8     int i=left,j=mid+1,k=left;
     9     while(i!=mid+1&&j!=right+1)
    10     {
    11         if(a[i]>a[j])
    12         {
    13             //count+=j-k;
    14             b[k++]=a[j++];
    15             count+=mid-i+1;
    16         }
    17         else
    18         {
    19             b[k++]=a[i++];
    20         }
    21     }
    22     while(i!=mid+1)
    23         b[k++]=a[i++];
    24     while(j!=right+1)
    25         b[k++]=a[j++];
    26     for(i=left; i<=right; i++)
    27         a[i]=b[i];
    28 }
    29 void Merge_sort(int *a,int left,int right)
    30 {
    31     if(left==right)
    32         return ;
    33     int mid=(left+right)>>1;
    34     Merge_sort(a,left,mid);
    35     Merge_sort(a,mid+1,right);
    36     Merge(a,left,mid,right);
    37 }
    38 int main()
    39 {
    40     while(scanf("%d",&n),n)
    41     {
    42         count=0;
    43         for(int i=0; i<n; i++)
    44             scanf("%d",&a[i]);
    45         Merge_sort(a,0,n-1);
    46         printf("%lld
    ",count);
    47     }
    48     return 0;
    49 }
    View Code
  • 相关阅读:
    Ubuntu 16 安装redis客户端
    crontab 参数详解
    PHP模拟登录发送闪存
    Nginx配置端口访问的网站
    Linux 增加对外开放的端口
    Linux 实用指令之查看端口开启情况
    无敌的极路由
    不同的域名可以指向同一个项目
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error
    Redis 创建多个端口
  • 原文地址:https://www.cnblogs.com/cxbky/p/4871794.html
Copyright © 2011-2022 走看看