zoukankan      html  css  js  c++  java
  • Ultra-QuickSort POJ 2299(归并排序)

    http://acm.hust.edu.cn/vjudge/contest/124435#problem/D

    题意:给出一个长度为n的数列,你每一次可以随意交换其中两个数字的位置。问你至少交换几次,才能使得这个数列是个单调递增数列。

    比赛时没做出来,(自然,比赛后也没做出来。。。

    找了度娘后,发现有三种方法(线段树, 树状数组, 归并排序),然而我一种也不会。

    **************************************************************************************************************************************

    下面介绍介绍归并排序:

    由于本题实际上就是要求逆序对(即满足i<j,a[i]>a[j]的数对)的个数。而我们再回顾一下归并排序的过程:

    假设回溯到某一步,后面的两部分已经排好序(就是说当前需要归并的两个部分都是分别有序的),假设这两个序列为

    序列a1:2 3 5 9  

    序列a2:1 4 6 8

    此时我们的目的就是要将a1和a2合并为一个序列。

    由于在没排序前a2序列一定全部都是在a1序列之后的,当我们比较a2的1与a1的2时,发现1<2按照归并的思想就会先记录下a2的1,而这里实际上就是对冒泡排序的优化,冒泡是将a2的1依次与a1的9,5,3,2交换就需要4次,而归并却只有一次就完成了,要怎么去记录这个4呢,实际上由于1比2小而2后面还有4个数,也就是说那我的结果就必须要+4,也就是记录a1序列找到第一个比a2某一个大的数,他后面还余下的数的个数就是要交换的次数。

    同时我们看a2的4时,a1中第一个比它大的数是5,5之后共有两个数,那结果就+2,。依次下去就可以计算出结果。但是由于我们任然没有改变归并排序的过程。所以复杂度还是O(nlogn)。

    #include <stdio.h>
    #include <string.h>
    #define maxn 500010
    int n, A[maxn], T[maxn];
    long long ans;
    
    void Merg_Sort(int x, int y)
    {
        if(y-x<=1) return ;
        int mid=x+(y-x)/2;
    
        Merg_Sort(x, mid);
        Merg_Sort(mid, y);
    
        int p=x, q=mid, i=x;
    
        while(p<mid || q<y)
        {
            if(q>=y || (p<mid && A[p]<=A[q])) T[i++]=A[p++];
            else//else的条件是(p==mid || A[q] < A[p])
            {
               if(p<mid) ans+=(mid-p);//由于是p<mid,所以此时也就是相当于 A[q] < A[p]
                T[i++] = A[q++]; //上面同时A[p]是第一个<A[q]的数,所以+后面还有的数(mid-p)
            }
        }
    
        for(i=x; i<y; i++)
            A[i] = T[i];
    }
    
    int main()
    {
        while(scanf("%d", &n),n)
        {
            memset(A, 0, sizeof(A));
            memset(T, 0, sizeof(T));
    
            for(int i=0; i<n; i++)
                scanf("%d", &A[i]);
    
            ans = 0;
    
            Merg_Sort(0, n);
    
            printf("%I64d
    ", ans);
        }
    
        return 0;
    }
    View Code

     

  • 相关阅读:
    在windows下拆卸Linux就是这么俭朴
    打点Linux下永中Office和桌面殊效的冲突
    Banshee 0.11.4
    ubuntu8.0中文输入法
    RedFlag 6.0 硬盘安置我解
    阅读器和把持体系和用户的IQ
    初试Fedora,最后还是Xubuntu
    VMware中放置Ubuntu后鼠标滚轮标题问题办理
    GNOME 的文件经管器将片面支撑标签式阅读
    ATI显卡开启fedora9的3d后果的一些条记
  • 原文地址:https://www.cnblogs.com/daydayupacm/p/5715324.html
Copyright © 2011-2022 走看看