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
  • 相关阅读:
    2019.12.14
    2019.12.17
    Jquery中用offset().top和offsetTop的比较
    wpquery调用前几篇文章的方法
    模仿百度百科的滚轮事件
    WordPress的默认循环
    WordPress自定义菜单和修改去除多余的css
    WordPress自定义循环
    WordPress创建多个page页面模板文件
    玩玩
  • 原文地址:https://www.cnblogs.com/cxbky/p/4871794.html
Copyright © 2011-2022 走看看