Ultra-QuickSort(CDQ分治+线段树或树状数组)

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.

题目链接
CDQ入门

这个题目其实不用这么麻烦,但是刚接触CDQ算法,就先借助这个简单的题目来理解一下。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAX_SIZE = 5e5+5;

struct node
{
    int Operat_Type, pos;
};
node order[MAX_SIZE<<1], temp[MAX_SIZE<<1];
int _array[MAX_SIZE], Sorted_Array[MAX_SIZE];
int n, num, Sorted_Num;
LL ans;

void CDQ(int left, int right)
{
    LL sum = 0;
    if(left == right)   return ;
    int mid = (left+right)>>1;
    CDQ(left, mid), CDQ(mid+1, right);
    int counter = left, Left_pos = left, Right_pos = mid+1;
    while(Left_pos <= mid && Right_pos <= right)
    {
        if(order[Left_pos].pos > order[Right_pos].pos)
        {
            if(order[Left_pos].Operat_Type == 1)    ++sum;  //左边更新,记录会对右边提供的逆序对的数量
            temp[counter++] = order[Left_pos++];
        }
        else
        {
            if(order[Right_pos].Operat_Type == 2)   ans += sum; //右边查询,每次都加上左边提供的逆序对个数
            temp[counter++] = order[Right_pos++];
        }
    }
    while(Left_pos <= mid)  temp[counter++] = order[Left_pos++];
    while(Right_pos <= right)
    {
        if(order[Right_pos].Operat_Type == 2)   ans += sum;
        temp[counter++] = order[Right_pos++];
    }
    for(int i = left; i <= right; i++)    order[i] = temp[i];
}

int main()
{
    while(~scanf("%d", &n), n)
    {
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &_array[i]);
            Sorted_Array[i] = _array[i];
        }
        sort(Sorted_Array+1, Sorted_Array+1+n);
        Sorted_Num = unique(Sorted_Array+1, Sorted_Array+1+n) - (Sorted_Array+1);
        num = 0;
        for(int i = 1; i <= n; i++)
        {
            int pos = lower_bound(Sorted_Array+1, Sorted_Array+1+Sorted_Num, _array[i])-Sorted_Array;
            num++;
            order[num].Operat_Type = 1; order[num].pos = pos;
            num++;
            order[num].Operat_Type = 2; order[num].pos = pos;
        }
        ans = 0;
        CDQ(1, num);
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40788897/article/details/89364796
今日推荐