POJ2299 原题链接:http://poj.org/problem?id=2299
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 63588 | Accepted: 23705 |
Description
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
Output
Sample Input
5 9 1 0 5 4 3 1 2 3 0
Sample Output
6 0
原题大意:输入一串数据,求它的逆序数;
思路:暴力的方法肯定超时,用树状数组可以将复杂度降到O(nlogn);
这道题大体的思路为:
1.开一个能大小为这些数的最大值的树状数组,并全部置0;
2.从头到尾读入这些数,每读入一个数就更新树状数组,查看它前面比它小的已出现过的有多少个数sum;
3.用当前位置减去该sum,就可以得到当前数导致的逆序对数了。把所有的加起来就是总的逆序对数;
但是,题目给的一个数的范围最大为999,999,999显然我们的树状数组不能开到那么大;这里要用到离散化,就是把输入的所有数离散化到1~n的范围内在进行1~3步的操作;
离散化过程:
1.创建一个结构体
const int N=5e5+10;
typedef struct{
int val; //输入值
int pos; //原下标
}NODE;
NODE node[N];
在创建一个数组a[N];
把node[N]按照val的值从小到大排列之后令 a[node[i].pos]=i (i=1,2,3,4,5,6...n)
过程如下:
1.拿题目第一个样例,输入的为 val: 9 1 0 5 4;
其原下标为pos: 1 2 3 4 5;
node[i]的 i: 1 2 3 4 5;
2.排序之后 val: 0 1 4 5 9
pos: 3 9 5 4 1
i: 1 2 3 4 5