TOJ 1455.Ultra-QuickSort(分治经典题目)

题目链接
题目大意很简单,就是要使一个序列非递减排序需要交换多少次,每次交换相邻的数字对。要明白本题要求的实际上是逆序对数。故可以采用归并排序并计算逆序数。
这道题是非常经典的分治题目,通过这道题我的收获有:

  • 学习归并排序的写法

  • 怎样在归并中计算逆序对数

  • cstring中的memcpy的用法

#include 
#include 
using namespace std;
int arr[500002],lef[500002],righ[500002];
long long sum;
const int Max = 2000000000;
void merge_sort(int begin ,int end){
    if(begin == end) return ;
    int mid = (begin + end)/2;
    merge_sort(begin,mid);
    merge_sort(mid+1,end);
    memcpy(lef+1,arr+begin,sizeof(int) * (mid-begin+1));
    memcpy(righ+1,arr+mid+1,sizeof(int) * (end-mid));
    int left=1,right=1;
    int left_num=mid-begin+1;
    lef[left_num+1]=righ[end-mid+1] = Max;
    for(int i=begin;i<=end;i++){
        if(lef[left]>righ[right]){
            arr[i]=righ[right++];
            sum+= left_num;
        }
        else{
            arr[i]=lef[left++];
            left_num--;
        }
    }
}

int main()
{
    int n;
    while(scanf("%d",&n) && n){
        for(int i=1;i<=n;i++)
            scanf("%d",&arr[i]);
        sum=0;
        merge_sort(1,n);
        printf("%lld\n",sum);
    }
}

你可能感兴趣的:(分治,经典题目)