zoukankan      html  css  js  c++  java
  • POJ 2299 Ultra-QuickSort (求逆序数:离散化+树状数组或者归并排序求逆序数)

    Ultra-QuickSort
    Time Limit: 7000MS   Memory Limit: 65536K
    Total Submissions: 55048   Accepted: 20256

    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
    题意:就是求逆序数
    分析:有几种方法,这里用了两个
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 500010;
    int F[MAXN];
    int a[MAXN];
    int n;
    pair<int,int>p[MAXN];
    void update(int x,int val)
    {
        while(x<=n)
        {
            F[x]+=val;
            x+=x&-x;
        }
    }
    int query(int x)
    {
        int res=0;
        while(x>0)
        {
            res+=F[x];
            x-=x&-x;
        }
        return res;
    }
    
    int main()
    {
        while(scanf("%d",&n)==1&&n)
        {
            memset(F,0,sizeof(F));
            memset(a,0,sizeof(a));
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&p[i].first);
                p[i].second=i;
            }
            sort(p+1,p+n+1);
            a[p[1].second]=1;
            for(int i=2;i<=n;i++)
            {
                if(p[i].first!=p[i-1].first) a[p[i].second]=i;
                else a[p[i].second]=a[p[i-1].second];
            }
            long long ans=0;
            for(int i=1;i<=n;i++)
            {
                update(a[i],1);
                ans+=query(n)-query(a[i]);
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    /*
     用归并排序求逆序数
     */
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 500010;
    int a[MAXN],b[MAXN],c[MAXN];
    long long ans;
    
    //将已经排好的l-mid,mid+1-r进行归并
    void merge(int *a,int l,int mid,int r)
    {
        for(int i=0,j=l;j<=mid;j++)
            b[i++]=a[j];
        int len1=mid-l+1;
        for(int i=0,j=mid+1;j<=r;j++)
            c[i++]=a[j];
        int len2=r-mid;
        int i=0,j=0,k=l;
        while(i<len1&&j<len2&&k<=r)
        {
            if(b[i]<=c[j]) a[k++]=b[i++];
            else
            {
                a[k++]=c[j++];
                ans+=len1-i;//逆序数就是累加后面比自己小的数的个数
                //此时b[i]>c[j],那么c[j]会给b[i]后面的len1-i个数造成逆序数
            }
        }
        while(i<len1) a[k++]=b[i++];
        while(j<len2) a[k++]=c[j++];
    }
    void merge_sort(int *a,int l,int r)
    {
        if(l<r)
        {
            int mid=(l+r)/2;
            merge_sort(a,l,mid);
            merge_sort(a,mid+1,r);
            merge(a,l,mid,r);
        }
    }
    
    int main()
    {
        int n;
        while(scanf("%d",&n)==1&&n)
        {
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            ans=0;
            merge_sort(a,1,n);
            printf("%lld
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    Python 存储引擎 数据类型 主键
    Python 数据库
    Python 线程池进程池 异步回调 协程 IO模型
    Python GIL锁 死锁 递归锁 event事件 信号量
    Python 进程间通信 线程
    Python 计算机发展史 多道技术 进程 守护进程 孤儿和僵尸进程 互斥锁
    Python 异常及处理 文件上传事例 UDP socketserver模块
    Python socket 粘包问题 报头
    Django基础,Day7
    Django基础,Day6
  • 原文地址:https://www.cnblogs.com/wangdongkai/p/5742647.html
Copyright © 2011-2022 走看看