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.
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 0Sample Output
6
0
这道题归并排序也可以做,树状数组与前缀和的不同在于它适用于在不断修改元素的基础上不断查询区间和,减少大量复杂度,利用了二进制的思想i&-i相当于i*2,这样复杂度变成了log级别,每一个和bit[i],中的元素的个数不一样,但是确有一定的规律。https://www.cnblogs.com/hsd-/p/6139376.html这个链接讲的很详细,值得参考,这道题每个元素不一样,对元素离散化的时候才容易了些,出现相同元素就要去重,这个就相对麻烦了,还有就是结果用longlong表示,刚开始用int WA了一次,这个也值得注意。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
struct t
{
int value;
int pos;
} f[500003];
int a[500003],bit[500003],n;
bool cmp(t x,t y)
{
return x.value<y.value;
}
void add(int i)
{
while(i<=n)
{
bit[i]+=1;
i+=i&-i;
}
}
long long summ(int i)
{
long long int s=0;
while(i>0)
{
s+=bit[i];
i-=i&-i;
}
return s;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
int u;
for(int i=1; i<=n; i++)
{
f[i].pos=i;
scanf("%d",&f[i].value);
}
sort(f+1,f+n+1,cmp);
memset(bit,0,sizeof(bit));
for(int i=1; i<=n; i++)
{
a[f[i].pos]=i;
}
long long int sum=0;
for(int i=1; i<=n; i++)
{
add(a[i]);
sum+=i-summ(a[i]);
}
printf("%lld\n",sum);
}
}