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算法,就先借助这个简单的题目来理解一下。
#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;
}