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.
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
题意:给出长度为n的序列,每次只能交换相邻的两个元素,问至少要交换几次才使得该序列为递增序列。
思路:一个乱序序列的 逆序数 = 在只允许相邻两个元素交换的条件下, 得到有序序列的交换次数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 500010;
int num[maxn], tree[maxn];
int n;
long long ans = 0;
struct node
{
int value, sum;
};
node arr[maxn];
//提取最低位;
int lowbit(int value)
{
return value&(-value);
}
//单点更新(给value位置上加1)n为所有元素的个数;
void build(int value)
{
for(int i=value; i<=n; i+=lowbit(i))
{
tree[i]+=1;
}
}
//区间查询,计算数组中1-value的和;
int getsum(int value)
{
int result = 0;
for(int i=value; i>=1; i-=lowbit(i))
{
result+=tree[i];
}
return result;
}
//按value升序排序;
bool cmp(node n1, node n2)
{
return n1.value<n2.value;
}
int main()
{
while(scanf("%d",&n)==1&&n)
{
ans = 0;
memset(tree, 0, sizeof(tree));
for(int i=1; i<=n; i++)
{
scanf("%d", &arr[i].value);
arr[i].sum = i;
}
sort(arr+1, arr+n+1, cmp);
//标记原序列中
for(int i=1; i<=n; i++)
{
num[arr[i].sum] = i;//原序列的第sum个是重新排序后的第i个;
}
//
for(int i=1; i<=n; i++)
{
build(num[i]);
ans+=i-getsum(num[i]);
}
printf("%I64d\n", ans);
}
return 0;
}