標籤:樹狀數組
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
59105431230
Sample Output
60
解題思路:
題目大意是給一個數列,相鄰兩個進行交換,使之按從小到大排序,問最少交換幾次。該題和之前的做的Janan是一個類型的,都是求逆序對。唯一痛點就是資料特別大,數列中的元素值可以達到999999999,樹狀數組不可能開這麼大。但由於數列最多有500000個數,所以可以進行離散化處理,把數列中的元素壓縮到1-500000之間。離散化就是將輸入的值與下標相對應,可以用結構體實現,然後對輸入的值進行從小到大排序,再用一個數組去儲存其下標的值。答案會超int範圍,得用Int64儲存。
AC代碼:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int maxn = 500005;__int64 c[maxn];struct node{ int a, b; // a儲存輸入的值,b儲存其座標}p[maxn];bool cmp(node v, node s){ return v.a < s.a;}int lowbit(int a){ return a & (-a);}void Update(int a){ while(a < maxn) { c[a] += 1; a += lowbit(a); }}__int64 Sum(int a){ __int64 sum = 0; while(a > 0) { sum += c[a]; a -= lowbit(a); } return sum;}int main(){ int n, a[maxn]; __int64 ans; while(scanf("%d", &n) && n) { ans = 0; memset(c, 0, sizeof(c)); for(int i = 1; i <= n; i++) { scanf("%d", &p[i].a); p[i].b = i; } sort(p + 1, p + n + 1, cmp); for(int i = 1; i <= n; i++) // 離散化處理 a[p[i].b] = i; for(int i = 1; i <= n; i++) { ans += i - Sum(a[i]) - 1; // 要-1,因為算的是輸入該值之前的元素個數 Update(a[i]); } printf("%I64d\n", ans); } return 0;}