poj2299 Ultra-QuickSort&&NYOJ117 求逆序数 (树状数组求逆序对数+离散化)+(归并排序)
来源:互联网 发布:grace出血评分软件 编辑:程序博客网 时间:2024/05/16 14:07
Ultra-QuickSort
Time Limit: 7000MS Memory Limit: 65536KTotal Submissions: 42087 Accepted: 15296
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/*之前用归并排序做,竟然超时。。。。很郁闷,明明可以的,,我也没再写归并排序,这个事树状数组做的、加油!!!Time:2014-9-2*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAX=500005;struct Node{int val;int pos;}node[MAX];int C[MAX],hash[MAX],N;bool cmp(const Node a,const Node b){if(a.val==b.val) return a.pos<b.pos;//因为位置从小到大开始检索,将位置大的放到后边避免重复 return a.val<b.val;//此处排序不能等于,如果值相等,位置按从小到大 }int lowbit(int x){return x&(-x);}void Modify(int x,int v){while(x<=N){C[x]+=v;x+=lowbit(x);}}int nSum(int x){int sum=0;while(x>0){sum+=C[x];x-=lowbit(x);}return sum;} void solve(){while(scanf("%d",&N),N){for(int i=1;i<=N;i++){scanf("%d",&node[i].val);node[i].pos=i;//标记值的位置 }sort(node+1,node+N+1,cmp);//值相等时,位置小的在前,检索的时候按位置从小到大检索,//如果位置从大到小,相同值的时候检索后边的时候会少掉前边的,这样求出来的i-nSum(hash[i])就会多一个,因为位置比它小的还没加到里边,树状数组是按位置来相加的 for(int i=1;i<=N;i++) hash[node[i].pos]=i;//将值位置标记为对应的hash值,将价值离散化,将把原来的位置按价值排序后的顺序进行标记,下边找逆序对的时候按原来的位置进行寻找 for(int i=1;i<=N;i++) C[i]=0;long long ans=0;for(int i=1;i<=N;i++){// i 表示位置,从第一个开始 Modify(hash[i],1); ans+=i-nSum(hash[i]);//排序方式可以使相同的值求逆序对为 0,将其减掉 //hash[i]表示第 i 个位置的hash值,用 i 减之前位置小于等于它的个数,就是比它大的个数 } printf("%lld\n",ans);}}int main(){solve();return 0;}/*以下为NYOJ117 的代码,代码一样很费解的是,昨天写的归并排序代码,超时。。。。至今不知道为什么Time:2014-9-3 0:09*/#include<cstdio>#include<cstring>#include<climits>#include<algorithm>using namespace std;const int MAX=500000+20;int a[MAX<<1],t1[MAX],t2[MAX];long long ans;void merge(int start,int end,int mid){int i,j,k;for(k=0,i=start;i<=mid;i++)t1[k++]=a[i];t1[k]=INT_MAX;for(k=0,i=mid+1;i<=end;i++)t2[k++]=a[i];t2[k]=INT_MAX;i=j=0;for(k=start;k<=end;k++){if(t1[i]<=t2[j]){a[k]=t1[i++];}else{ans+=(mid-start+1-i);a[k]=t2[j++];}}}void merge_sort(int start,int end){if(end>start){int mid=((start+end)>>1);merge_sort(start,mid);merge_sort(mid+1,end);merge(start,end,mid);}}void solve(){int T,N;scanf("%d",&T);while(T--){scanf("%d",&N);for(int i=0;i<N;i++)scanf("%d",&a[i]);ans=0;merge_sort(0,N-1);printf("%lld\n",ans);}} int main(){solve();return 0;}/*以下为超时代码,,我也不知道为什么。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。无语*/#include<stdio.h>#include<string.h>#include<limits.h> const int MAX=500020;long long cnt;int a[MAX<<1],t1[MAX],t2[MAX];void Merge(int start,int mid,int end){int i,j,k;for(k=0,i=0;i<=mid;i++)t1[k++]=a[i];t1[k]=INT_MAX;for(k=0,i=mid+1;i<=end;i++)t2[k++]=a[i];t2[k]=INT_MAX;//将前后的最后一个设成无穷大,到了最后一个如果没有合并完,会一直合并 for(i=j=0,k=start;k<=end;k++){if(t1[i]<=t2[j]){a[k]=t1[i++];}else{cnt+=(mid-start+1-i);a[k]=t2[j++];//如果前边比后边的大,由后边那个数与前边集合能组成的逆序对数为包括i--mid的个数 }}}void merge_Sort(int start,int end){if(end>start){int mid=(start+end)>>1;merge_Sort(start,mid);merge_Sort(mid+1,end);Merge(start,mid,end);}}void solve(){int T,N;scanf("%d",&T);while(T--){scanf("%d",&N);for(int i=0;i<N;i++)scanf("%d",&a[i]);cnt=0;merge_Sort(0,N-1);printf("%lld\n",cnt);}}int main(){solve();return 0;}
0 0
- poj2299 Ultra-QuickSort&&NYOJ117 求逆序数 (树状数组求逆序对数+离散化)+(归并排序)
- nyoj117求逆序数(离散化+树状数组/归并排序)
- 【树状数组】poj2299 Ultra-QuickSort(离散化+树状数组求逆序数)
- POJ2299 Ultra-QuickSort——树状数组求逆序数+离散化
- poj2299 Ultra-QuickSort(树状数组求逆序数,离散化)
- poj2299 Ultra-QuickSort(离散化+树状数组求逆序数)
- 【树状数组--求逆序数(离散化)】poj2299 Ultra-QuickSort
- POJ2299 Ultra-QuickSort 归并排序和逆序数,树状数组
- POJ-2299 Ultra-QuickSort (树状数组 离散 求逆序对数)
- Ultra-QuickSort(离散化+树状数组求逆序数)
- POJ2299 Ultra-QuickSort 归并排序求逆序数对
- (归并排序求逆序数) poj2299 Ultra-QuickSort
- POJ2299-Ultra-QuickSort (归并排序求逆序数)
- POJ2299 Ultra-QuickSort (归并排序求逆序数模板)
- Ultra-QuickSort poj2299 (归并排序 求逆序数对)
- POJ2299 Ultra-QuickSort(归并排序,求逆序数)
- POJ2299 Ultra-QuickSort(树状数组求逆序数)
- POJ2299:Ultra-QuickSort(树状数组求逆序数)
- vim常用快捷键
- 多线程安全
- pyInstaller
- SVM模型预测
- TCP/IP详解--TCP/IP可靠的原理 滑动窗口 拥塞窗口
- poj2299 Ultra-QuickSort&&NYOJ117 求逆序数 (树状数组求逆序对数+离散化)+(归并排序)
- Longest Substring Without Repeating Characters
- R相关分析
- 求子数组之和的最大值——编程之美 2.14 扩展问题 正确实现
- 晶体一秒变晶振,成本直降60%!
- Linux命令笔记
- 约瑟夫问题专题
- BootStrap -- Table
- Empire of the sums