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.
Ultra-QuickSort produces the output
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
解题思路
直接求逆序对来完成
AC代码
#include <stdio.h>
#include<string.h>
#include <algorithm>
using namespace std;
int b[500005], c[500005];
int n;
struct Node
{
int num, id;
//定义结构体,使数值与位置一一对应被记录下来
}node[500005];
bool cmp(Node a, Node b)
{
return a.num < b.num;
}
int lowbit(int x)
{
return x&(-x);
}
void update(int i, int delta)
{
while( i <= n )
{
c[i] += delta;
i += lowbit(i);
}
}
int get_sum(int i)
{
int sum = 0;
while( i>0 )
{
sum += c[i];
i -= lowbit(i);
}
return sum;
}
int main()
{
int i;
long long ans;
while(scanf("%d", &n), n)
{
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
for(i=1; i<=n; i++)
{
scanf("%d", &node[i].num);
node[i].id = i;
//id记录了原位置,然后结构体非降序排序
}
sort(node+1, node+n+1, cmp);
b[ node[1].id ] = 1;
//b[]数组记录了原位置对应的现位置
for(i=2; i<=n; i++)
{
if(node[i].num != node[i-1].num)
b[ node[i].id ] = i;
else b[ node[i].id ] = b[ node[i-1].id ];
}
ans=0;
for(i=1; i<=n; i++)
{
update(b[i], 1);
//想象又一个数组,b[1]是原NO1数对应的现在位置X_NO1,更新+1
ans += (get_sum(n)-get_sum(b[i]));
//原NO2数对应现位置X_NO2,更新+1
}
//如果原NO2数 < 原NO1数,则X_NO2 < X_NO1,所以此时ans会记录下原序列中前面比自己大的数
printf("%I64d\n", ans);
}
return 0;
}