POJ--2299 Ultra-QuickSort(离散化 + 求逆序数)
2016-01-28 20:16
645 查看
传送门:Ultra-Quicksort
题意:求一个序列的逆序数。
分析:数据范围太大,需要先离散化处理。所谓离散化,就是缩小数与数之间的间隔,但要保证原来的大小关系不变。
然后是求逆序数,用归并排序的算法或者树状数组皆可。
-----1. 树状数组求逆序数
-----2. 归并求逆序数
题意:求一个序列的逆序数。
分析:数据范围太大,需要先离散化处理。所谓离散化,就是缩小数与数之间的间隔,但要保证原来的大小关系不变。
然后是求逆序数,用归并排序的算法或者树状数组皆可。
-----1. 树状数组求逆序数
# include <iostream> # include <cstdio> # include <cstring> # include <algorithm> using namespace std; //AC 407ms const int maxn = 500000 + 5; int a[maxn], c[maxn]; int n; struct num{ int val, pos; bool operator<(const num &a) const{ return val < a.val; } }b[maxn]; int lowbit(int x) { return x & -x; } void add(int x) { for(int i = x; i <= maxn; i += lowbit(i)) c[i]++; } int sum(int x) { int s = 0; for(int i = x; i ; i -= lowbit(i)) s += c[i]; return s; } void solve() { long long ans = 0; for(int i = 1; i <= n; ++i) { add(a[i]); ans += i - sum(a[i]); } cout << ans << endl; } void process() //离散化处理 { for(int i = 1; i <= n; ++i) { scanf("%d", &b[i].val); b[i].pos = i; } stable_sort(b + 1, b + n + 1); for(int i = 1; i <= n; ++i) a[b[i].pos] = i; } int main() { while(cin >> n && n) { process(); memset(c, 0, sizeof(c)); solve(); } return 0; }
-----2. 归并求逆序数
# include <iostream> # include <cstdio> # include <cstring> # include <algorithm> using namespace std; //AC, 516ms const int maxn = 500000 + 5; int a[maxn], tmp[maxn]; int n; long long ans; struct num{ int val, pos; bool operator<(const num &a) const{ return val < a.val; } }b[maxn]; void Merge(int a[], int tmp[], int left, int mid, int right) { int i = left, j = mid + 1; int k = left; while(i <= mid && j <= right) { if(a[i] < a[j]){ tmp[k++] = a[i++]; } else{ ans += mid - i + 1; tmp[k++] = a[j++]; } } while(i <= mid) tmp[k++] = a[i++]; while(j <= right) tmp[k++] = a[j++]; for(i = left; i <= right; ++i) a[i] = tmp[i]; } void MSort(int a[], int tmp[], int left, int right) { if(left < right) { int mid = (left + right) >> 1; MSort(a, tmp, left, mid); MSort(a, tmp, mid + 1, right); Merge(a, tmp, left, mid, right); } } void solve() { MSort(a, tmp, 1, n); cout << ans << endl; } void process() { for(int i = 1; i <= n; ++i) { scanf("%d", &b[i].val); b[i].pos = i; } stable_sort(b + 1, b + n + 1); for(int i = 1; i <= n; ++i) a[b[i].pos] = i; } int main() { while(cin >> n && n) { ans = 0; process(); solve(); } return 0; }
相关文章推荐
- RM格式压缩电影软件 Easy RealMedia Producer Full V1.94 下载
- 在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
- 比较简单的jquery教程 Easy Ajax with jQuery 中文版全集第1/3页
- Easy RM RMVB to DVD Burner v1.3.8 汉化版 下载 附注册码
- C++归并算法实例
- Expandable "Detail" Table Rows
- C语言实现排序算法之归并排序详解
- linux下安装easy_install的方法
- 归纳整理文件Easy Duplicate Finder2.24 破解版
- DM*** and Easy *** Server with ISAKMP Profiles
- easy ***
- cisco packet tracer 5.3 实现基于3A的easy ***
- [Leetcode题目]19. Remove Nth Node From End of List
- [Leetcode题目]21. Merge Two Sorted Lists
- [Leetcode题目]83. Remove Duplicates from Sorted List
- [Leetcode题目]160. Intersection of Two Linked Lists
- [Leetcode题目]203. Remove Linked List Elements
- [Leetcode题目]206. Reverse Linked List
- [Leetcode题目]234. Palindrome Linked List
- 初学ACM - 组合数学基础题目PKU 1833