Ultra-QuickSort(逆序数)
来源:互联网 发布:词典推荐 知乎 魏 编辑:程序博客网 时间:2024/06/09 00:05
Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536KTotal Submissions: 62759 Accepted: 23385
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题意是求一组数的逆序数,首先搞清楚逆序数是什么,即一组数中逆序对的个数,如 3,4,5,1中逆序对为(3,1),(4,1),所以逆序数为2。
求逆序数的方法:用树状数组,用从c[]表示树状数组,组用setsum(i)函数求当前序列中小于等于i的数的个数,用i-getsum(i)得到i前面比i大的数。重点是为什么getsum(i)表示i前面比i小的数的个数呢??前面明明用此函数求前i项数的和,此题先把c[]全设值为0,由于数是不重复的,我们把读入数x时设置第x这个位置的值为1,c[x]=1,当读入第二个数y时,把在第y个位置的数为1,即c[y],如果y比x大,肯定c[y]在从c[x]后面,这样就c[y]前就有一个1,就是有一个比自己小的数,就会在这样可以无形得到一个有顺序(从小到大)的序列。 比如给出一组数 5 3 6 2 1,读入第一个数此时得到c是 0 0 0 1 0;读入3时,c为0 0 1 1 0;读入6时 c为 0 0 1 1 1, 发现当时读入的1的位置前面出现的1的个数就是比自己小的数的个数
于是得到代码:
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define ll long long#define maxn 100005using namespace std;int c[maxn],n;int low_bit(int i){ return i&(-i);}void update(int i,int v){ while(i<=n){ c[i]+=v; i+=low_bit(i); }}//前i项中比i小的数的个数int get_sum(int i){ int res=0; while(i){ res+=c[i]; i-=low_bit(i); } return res;}int main(){ while(scanf("%d",&n),n) { memset(c,0,sizeof(c)); int ans=0; for(int i=1;i<=n;i++) { int a; scanf("%d",&a); update(i,1); ans+=i-get_sum(a); } printf("%d\n",ans); } return 0;}
但是由上面我们知道c[]中放的是输入变量,此题数值较大,直接开数组肯定不行,但n的值较小,于是我们把它离散化。
假如现在有一些数:1234 98756 123456 99999 56782,由于1234是第一小的数,所以reflct[1]=1;依此,有reflect[5]=2,reflect[2]=3,reflect[4]=4,reflect[3]=5;这 样转化后并不影响原来数据的相对大小关系,且把c[]范围缩小了。
于是得到代码:
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int N=500005;int c[N],reflect[N], n;struct node{ int val; int pos;}nd[N];bool cmp(node p1,node p2){ return p1.val<p2.val;}int lowbit(int x){ return x&(-x);}int updata(int x){ while(x<=n) { c[x]+=1; x+=lowbit(x); }}int getsum(int x){ int ans=0; while(x>0) { ans+=c[x]; x-=lowbit(x); } return ans;}int main(){ while(~scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) { scanf("%d",&nd[i].val); nd[i].pos=i; } sort(nd+1,nd+n+1,cmp); for(int i=1;i<=n;i++) reflect[nd[i].pos]=i; for(int i=1;i<=n;i++) c[i]=0; long long ans=0; for(int i=1;i<=n;i++) { updata(nd[i].pos); ans+=i-getsum(nd[i].pos); } printf("%lld\n",ans); }}
阅读全文
0 0
- Ultra-QuickSort(逆序数)
- Ultra-QuickSort(归并排序+逆序数)
- 10810 - Ultra-QuickSort(求逆序数)
- POJ 2299 Ultra-QuickSort(逆序数)
- 2299 Ultra-QuickSort(逆序数)
- 逆序数 poj2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort(归并排序求逆序数)
- 10810 - Ultra-QuickSort(归并排序求逆序数)
- PKU Ultra-QuickSort (树状数组求逆序数)
- POJ2299 Ultra-QuickSort(树状数组求逆序数)
- uva 10810 - Ultra-QuickSort(归并求逆序数)
- Ultra-QuickSort(归并排序记录逆序数)
- 复习--Ultra-QuickSort(归并排序求逆序数)
- poj 2299 Ultra-QuickSort (归并排序,逆序数)
- POJ 2299 Ultra-QuickSort(逆序数、分治)
- Ultra-QuickSort(离散化+树状数组求逆序数)
- POJ 2299 Ultra-QuickSort(逆序数 树状数组)
- poj 2299 Ultra-QuickSort(树状数组 / 求逆序数)
- 使用Node.js+Socket.IO搭建WebSocket实时应用
- Android5.0特性
- Insertion Sort List问题及解法
- ios cookie概念介绍
- VS2013 编写汇编程序
- Ultra-QuickSort(逆序数)
- [cs231n之第四课]Backprop
- Spring IoC有什么好处呢
- 贪心算法——招聘会
- vue2.0入门教程-笔记1
- 40编程练习
- 文章
- 1014. 福尔摩斯的约会
- C# 的TCPClient异步连接与异步读数据