Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 62342 | Accepted: 23200 |
Description
![](https://i-blog.csdnimg.cn/blog_migrate/b3530eaa8fa98ef394d3639722240a8c.jpeg)
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
Source
思路:其实就是求这些数每个数的逆序数的和。先将这些数据离散化,每一个数对应一个编号是连续的整数。要使这些数升序排序,就要求这些编号的逆序数之和。但树状数组每次查询都是查比它小的,不能做到逆序,所以我们可以将这些数据以降序来排。再用树状数组求的就是他们的逆序和。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=500105;
int n;
int tr[maxn];
struct node
{
int x,p;
}q[maxn];
bool cmp(node a,node b)
{
return a.x>b.x;
}
int lowbit(int i)
{
return i&(-i);
}
void update(int x,int n)
{
while(x<=n)
{
tr[x]+=1;
x+=lowbit(x);
}
}
int query(int n)
{
int sum=0;
while(n>0)
{
sum+=tr[n];
n-=lowbit(n);
}
return sum;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
memset(tr,0,sizeof(tr));
for(int i=1;i<=n;i++)
{
scanf("%d",&q[i].x);
q[i].p=i;
}
sort(q+1,q+1+n,cmp);
long long res=0;
for(int i=1;i<=n;i++)
{
res+=query(q[i].p);
update(q[i].p,n);
}
printf("%lld\n",res);
}
return 0;
}