poj 2299 Ultra-QuickSort(归并排序 树状数组)

题意 :交换相邻的两个数来排序 最少交换几次

 

思路:

题意可以转化成求 数列中存在几个逆序数

可以看作冒泡排序 但是复杂度过高 可以用归并排序 和离散化的树状数组来完成

(注意 n<=5000000 所以ans 要用 长整型 )

 

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

int a[5000000+100];

int t[5000000+100];

__int64 ans;

int l,r;

void merge(int x,int y)

{

    if(y-x>1)

    {

        int m=x+(y-x)/2;

        int p=x,q=m,i=x;

        merge(x,m);

        merge(m,y);

        while(p<m||q<y)

        {

            if(q>=y||(p<m&&a[p]<=a[q])) t[i++]=a[p++];

            else

                {

                    if(p<m)

                    {

                        //printf("%d %d...\n",a[p],a[q]);

                        ans+=(m-p);

                    }

                    t[i++]=a[q++];

                }

        }

        for(i=x;i<y;i++) a[i]=t[i];

       // printf("%d %d %d\n",x,m,y);  for(i=0;i<r;i++) printf("%d ",a[i]);  printf("\n\n\n");

    }

}

int main()

{

    int n;

    int i,j,k;

    while(scanf("%d",&n),n)

    {

        ans=0;

        for(i=0;i<n;i++)

        {

            scanf("%d",&a[i]);

        }

        //l=0;r=n;

        merge(0,n);

        printf("%I64d\n",ans);

    }

    return 0;

}

 

树状数组 

#include<cstdio>

#include<cmath>

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<iostream>

#include<algorithm>

using namespace std;

int n,c[500000+10],reflect[500000+10];

__int64 ans;



struct node

{

    int val,pos;

};

node a[500000+10];



int cmp(node x,node y)

{

    return x.val<y.val;

}

int lowbit(int x)

{

    return x&(-x);

}

int sum(int x)

{

    int ret=0;

    while(x>0)

    {

        ret+=c[x];

        x-=lowbit(x);

    }

    return ret;

}



void add(int x)

{

    while(x<=n)

    {

        c[x]+=1;

        x+=lowbit(x);

    }

}

int main()

{

    while(scanf("%d",&n),n)

    {

        ans=0;

        memset(c,0,sizeof(c));

        int i,j;

        for(i=1;i<=n;i++){ scanf("%d",&a[i].val); a[i].pos=i;}

        sort(a+1,a+n+1,cmp);

        for(i=1;i<=n;i++) {reflect[a[i].pos]=i;}



        for(i=1;i<=n;i++)

        {

            add(reflect[i]);

            ans+=i-sum(reflect[i]);

            printf("%I64d\n",ans);

        }

        printf("%I64d\n",ans);

    }

    return 0;

}

 

你可能感兴趣的:(Quicksort)