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.
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
离散化处理+树状数组求逆序
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n,Max;
int b[600006],c[500005];
struct Node
{
int value;
int index;
bool operator < (const Node& b) const
{
return value<b.value;
}
}node[500005];
int lowbit(int i)
{
return i&(-i);
}
void updata(int i,int data)
{
while(i<=Max)
{
c[i]+=data;
i+=lowbit(i);
}
}
long long sum(int i)
{
long long res=0;
while(i>0)
{
res+=c[i];
i-=lowbit(i);
}
return res;
}
int main()
{
int i,j;
while(scanf("%d",&n)&&n)
{
Max=0;
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
for(i=1;i<=n;i++)
{
scanf("%d",&node[i].value);
node[i].index=i;
if(Max<node[i].value)
Max=node[i].value;
}
sort(node+1,node+n+1);
b[ node[1].index ]=1;
for(i=2;i<=n;i++)//离散化处理
{
if(node[i].value==node[i-1].value)
b[ node[i].index ]=b[ node[i-1].index ];
else
b[ node[i].index ]=i;
}
long long ans=0;//经过离散化处理之后,n为原数组中最大的元素值
for(i=1;i<=n;i++)
{
updata(b[i],1);
//cout<<sum(n)<<" "<<i<<endl;//sum(n)=i;sum(n)随着更新次数变化
ans+=sum(n)-sum(b[i]);//sum(n),下标为b[i]的数组值为1的和
}//先更新后求和,先求和后更新均可。//b[i]前比b[i]大的元素个数
cout<<ans<<endl;
}
return 0;
}