Ultra-QuickSort
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 72891 | Accepted: 27322 |
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
题目链接走起~~~
题意介绍:题目是超级快排,实则求对这个数列进行冒泡排序所需要的交换次序,即求逆序数。简单理解:我们可以这样想,求交换多少次 即看这个数前方有多少比他大的即可,分两步具体解释方法:
1.树状数组在本题中的应用
将一个个数插入,在插入过程中我们可以判断,在当前数组中有多少个比他小的数,i - sum(d[i]) 就是有多少比他大的数
i是插入的个数,sum(d[i])比他小的数的个数。
2.什么叫做离散化
百度百科解释。
通俗一点讲就是在存数时防止数据过大过大,而把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。
具体操作就是不改变数据相对大小 的情况下用小数来代替大数。
例 1 99999999 888 23
-->1 4 3 2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 500100;
struct nod{
int val;
int pos;
}a[maxn]; // 开数组存储其值和位置方便离散化
int n, bit[maxn], d[maxn];
int lowbit(int n)
{
return n & (-n);
}
bool cmp(nod a, nod b)
{
return a.val < b.val;
}
void add(int i, int x) // 树状数组添加一个数
{
while(i <= n)
{
bit[i] += x;
i += i & -i;
}
}
int sum(int i) // 树状数组求取比i小的数的和
{
int s = 0;
while(i > 0)
{
s += bit[i];
i -= i & -i;
}
return s;
}
int main()
{
while(scanf("%d", &n) != EOF && n)
{
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i].val);
a[i].pos = i;
}
sort(a + 1, a + n + 1, cmp);
for(int i = 1; i <= n; i++)
{
d[a[i].pos] = i;
bit[i] = 0; // bit数组首先赋值为0,添加数时让他增加看前面有多少比他小的数
}
long long ans = 0;
for(int i = 1; i <= n; i++)
{
add(d[i], 1);
ans += i - sum(d[i]); // 求有多少个比她大的
}
printf("%lld\n", ans);
// cout<<" ----------"<<endl;
}
return 0;
}