zoukankan      html  css  js  c++  java
  • POJ 2299 UltraQuickSort (树状数组 或 归并排序)

    Ultra-QuickSort
    Time Limit: 7000MS   Memory Limit: 65536K
    Total Submissions: 30129   Accepted: 10760

    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
    

    Source

     
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn=500005;
    
    int n,c[maxn];
    int b[maxn];
    
    int lowbit(int x){
        return x&(-x);
    }
    
    int Sum(int p){
        int sum=0;
        while(p>0){
            sum+=c[p];
            p-=lowbit(p);
        }
        return sum;
    }
    
    void Update(int p,int val){
        while(p<=n){
            c[p]+=val;
            p+=lowbit(p);
        }
    }
    
    struct node{
        int num,id;
    }a[maxn];
    
    int cmp(node a,node b){
        return a.num<b.num;
    }
    
    int main(){
        while(scanf("%d",&n) && n){
            memset(b,0,sizeof(b));
            memset(c,0,sizeof(c));
            int i;
            for(i=1;i<=n;i++){
                scanf("%d",&a[i].num);
                a[i].id=i;
            }
            sort(a+1,a+n+1,cmp);
            b[a[1].id]=1;
            for(i=2;i<=n;i++)
                if(a[i].id!=a[i-1].id)
                    b[a[i].id]=i;
                else
                    b[a[i].id]=b[a[i-1].id];
            long long ans=0;
            for(i=1;i<=n;i++){
                Update(b[i],1);
                ans+=Sum(n)-Sum(b[i]);
            }
            printf("%I64d\n",ans);
        }
        return 0;
    }

    归并排序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int N=500010;
    const int INF=0x3f3f3f3f;
    
    int n;
    long long ans;
    
    void Cal(int num[],int low,int mid,int high){
        int len_L=mid-low+1;
        int len_R=high-mid;
        int* left=new int[len_L+2];
        int* right=new int[len_R+2];
        int i,j;
        for(i=1;i<=len_L;i++)
            left[i]=num[low+i-1];
        left[len_L+1]=INF;
        for(j=1;j<=len_R;j++)
            right[j]=num[mid+j];
        right[len_R+1]=INF;
    
        i=j=1;
        for(int k=low;k<=high;){
            if(left[i]<=right[j])
                num[k++]=left[i++];
            else{
                num[k++]=right[j++];
                ans+=len_L-i+1;
            }
        }
        delete left;
        delete right;
    }
    
    void Mergesort(int num[],int low,int high){
        int mid;
        if(low<high){
            mid=(low+high)>>1;
            Mergesort(num,low,mid);
            Mergesort(num,mid+1,high);
            Cal(num,low,mid,high);
        }
    }
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        int num[N];
        while(~scanf("%d",&n) && n){
            for(int i=1;i<=n;i++)
                scanf("%d",&num[i]);
            ans=0;
            Mergesort(num,1,n);
            printf("%lld\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    Linux网络与服务管理
    输入两个数据,如果输入数据之和为5的倍数,那么就算是输了,停止游戏;如果赢了,接着输入数据。
    switch语句
    计算一个三位数的个位,十位,百位之和
    单分支和双分支选择结构程序设计
    register变量
    static变量
    auto变量
    长双精度类型
    双精度类型变量
  • 原文地址:https://www.cnblogs.com/jackge/p/2843420.html
Copyright © 2011-2022 走看看