ZOJ-2386 Ultra-QuickSort 【树状数组求逆序数+离散化】
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
题解:
树状数组求逆序数,先离散化,不然1e9开不下,然后每次对一个数id[i],将树状数组中这个位置+1,统计这个位置的前缀和,然后用i-sum(id[i])(差实际上就是id[i]位置后缀和)就是这个数id[i]导致的逆序对数量。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define INF 0x3f3f3f3f 7 #define M(a, b) memset(a, b, sizeof(a)) 8 const int N = 5e5 + 10; 9 int c[N], id[N], n; 10 struct node { 11 int val, pos; 12 bool operator < (const node &rhs) const { 13 return val < rhs.val; 14 } 15 }a[N]; 16 17 int lowbit(int x) {return x & -x;} 18 19 void add(int x, int d) { 20 while (x <= n) { 21 c[x] += d; 22 x += lowbit(x); 23 } 24 } 25 26 int sum(int x) { 27 long long ret = 0; 28 while (x) { 29 ret += c[x]; 30 x -= lowbit(x); 31 } 32 return ret; 33 } 34 35 int main() { 36 while (scanf("%d", &n), n) { 37 M(c, 0); 38 for (int i = 1; i <= n; ++i) 39 scanf("%d", &a[i].val), a[i].pos = i; 40 sort(a+1, a+1+n); 41 for (int i = 1; i <= n; ++i) id[a[i].pos] = i; 42 long long ans = 0; 43 for (int i = 1; i <= n; ++i) { 44 add(id[i], 1); 45 ans += i-sum(id[i]); 46 } 47 printf("%lld\n", ans); 48 } 49 50 return 0; 51 }