Ultra-QuickSort 离散化+树状数组
来源:互联网 发布:安装win10 linux的pe 编辑:程序博客网 时间:2024/05/16 15:22
Ultra-QuickSort
Time Limit : 14000/7000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 32 Accepted Submission(s) : 15
Problem 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.
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
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
Source
PKU
TLE代码:
此题大意:找逆序数有多少个,逆序数就是那一个序列中,右边的数比左边的数大的个数之和。其实就是和找冒泡的次数一样,不过用冒泡来做,50万个数据直接死亡,这道题可以用树状数组来做,之前不会做,看到解题报告中有说树状数组可以,就开始尝试写,后来发现竟然可以这样想:每次找前面(左边)的数比自己大的个数的总和!!!这样子想的话树状数组可以轻松解决。 不过还有一个问题,就是他输入的数据的值很大0 ≤ a[i] ≤ 999,999,999,但是数据的数量不是很大n < 500,000 ,所以用到离散化解决!!!链接:http://poj.org/problem?id=2299代码:Cpp代码 #include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> using namespace std; int b[500005], c[500005]; int n; struct node { int num, id; }a[500005]; bool cmp(node a, node b) { return a.num < b.num; } void update(int i, int x) { while(i <= n) { c[i] += x; i += i&(-i); } } int sum(int i) { int sum = 0; while(i > 0) { sum += c[i]; i -= i&(-i); } return sum; } int main() { int i; long long ans; while(scanf("%d", &n), n) { memset(b, 0, sizeof(b)); memset(c, 0, sizeof(c)); for(i = 1; i <= n; i++) { scanf("%d", &a[i].num); //输入数值num a[i].id = i; //记录序号id } ///开始离散化 sort(a+1, a+n+1, cmp); //先排序 /*因为a[1].num是最小的,id是它的位置,所以b[a[1].id]=1最小, 最小的数变成1,第二小的变成2,如此类推从而达到离散化*/ b[a[1].id] = 1; for(i = 2; i <= n; i++) { if(a[i].num != a[i-1].num) b[a[i].id] = i; else b[a[i].id] = b[a[i-1].id]; } ///离散化完毕 ans = 0; for(i = 1; i <= n; i++) { update(b[i], 1); //这里很巧妙,每一次更新后,判断此数比左边的数小的数有多少 ans += (sum(n)-sum(b[i])); } //从而求到:右边的数比左边的数大的个数的总和 printf("%I64d\n", ans); } return 0; }
- Ultra-QuickSort 离散化+树状数组
- 树状数组的离散化 Ultra-QuickSort
- [树状数组][离散化]Ultra-QuickSort
- Ultra-QuickSort (树状数组离散化)
- Ultra-QuickSort(树状数组 + 离散化)
- poj2299 Ultra-QuickSort (树状数组+离散化)
- POJ Ultra-QuickSort (树状数组+离散化)
- POJ2299 Ultra-QuickSort 树状数组+离散化
- poj2299 Ultra-QuickSort 树状数组 + 离散化
- POJ2299-Ultra-QuickSort(树状数组+离散化)
- Ultra-QuickSort 【归并或树状数组+离散化】
- POJ 2299 Ultra-QuickSort【树状数组+离散化】
- poj 2299 Ultra-QuickSort(离散化+树状数组)
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- poj 2299 Ultra-QuickSort 离散化+树状数组
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- POJ 2299 Ultra-QuickSort(树状数组+离散化处理)
- POJ 2299 Ultra-QuickSort(树状数组+离散化)
- 算法导论 并查集
- Error:hbase.PleaseHoldException: Master is initializing
- 在HTML中实现动态的时钟
- 量子论浅谈
- 水哥 liunx之旅之输入法
- Ultra-QuickSort 离散化+树状数组
- 函数式编程初探
- 敏捷开发思路
- php运算符以及运算符短路
- simon手册翻译_part2
- 前进方向
- 关于java中split的使用
- 任天堂第一财季亏2.2亿美元 Wii销量不及同期50%
- 04 实例27的改编