首页 > 代码库 > Poj 2299 Ultra-QuickSort 树状数组 解法
Poj 2299 Ultra-QuickSort 树状数组 解法
本题的树状数组稍微有点特点,就是需要所谓的离散化一下,开始听这个名称好像很神秘的,不过其实很简单。
就是把一个数组arr的值,其中的值是不连续的,变成一组连续的值,因为这样他们的顺序是不变的,所以,不影响结果。
例如:9 1 0 5 4 ->变为:5 2 1 4 3看出他们的相对位置不变的。
9和5为最大值在第一个位置,1和2为第二大的值在第二个位置,0和1在第一个位置等,看出对应顺序了吗?
对,就是这么简单的方法, 就叫做离散化。
如果你对counting sort熟悉的话,那么这样的思想理解并写出程序是毫不费力的。
当然本题如果使用归并排序会更好,不过归并太简单了。
原题:http://poj.org/problem?id=2299
我们这里使用树状数组加上上面说的离散化。
class UltraQuickSort2299 { const static int SIZE = 500005; int *reflect, *tree; inline int lowbit(int x) { return x & (-x); } void update(int x, int val, int len) { while (x <= len) { tree[x] += val; x += lowbit(x); } } long long query(int x) { long long ans = 0; while (x > 0) { ans += tree[x]; x -= lowbit(x); } return ans; } struct Node { int val, pos; bool operator<(const Node a) const { return val < a.val; } }; Node *arr; public: UltraQuickSort2299():arr((Node *)malloc(sizeof(Node) * SIZE)), tree((int *)malloc(sizeof(int) * SIZE)), reflect((int *)malloc(sizeof(int) * SIZE)) { int N; while (scanf("%d", &N) && N != 0) { for (int i = 1; i <= N; i++) { scanf("%d", &arr[i].val); arr[i].pos = i; } std::sort(arr+1, arr+N+1); for (int i = 1; i <= N; i++) { reflect[arr[i].pos] = i;//所谓的离散化,即对应到新的值,相对位置不变,下标记得变为1起点,如此倒腾的思维带counting sort的思维 } std::fill(tree, tree+N+1, 0); long long ans = 0; for (int i = 1; i <= N; i++) { update(reflect[i], 1, N); ans += i - query(reflect[i]); } printf("%lld\n", ans); } } ~UltraQuickSort2299() { free(tree); free(arr); free(reflect); } };
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。