【解题报告】POJ2299 超快速排序
解题思路:
归并排序求逆序对
归并排序使我们众所周知的,我们只要在归并排序中计算每一个子序列中的逆序对数,我们就可以计算出总的逆序对数了,也就是
cnt+=mid−i+1
然后就完成了这道题
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <iostream> #include <cstring> using namespace std; int n; long long cnt; const int maxn=500005; long long a[maxn]; long long b[maxn]; void merge_sort(int l,int r) { if(r>l) { int mid=(l+r)/2; int i=l; int p=l,q=mid+1; merge_sort(l,mid); merge_sort(mid+1,r); while(p<=mid||q<=r) { if(q>r||(p<=mid&&a[p]<=a[q])) b[i++] = a[p++]; else { b[i++]=a[q++]; cnt+=mid-p+1; } } for(i=l;i<=r;i++) a[i]=b[i]; } } int main() { while(cin>>n&&n) { for(int i=1;i<=n;i++) cin>>a[i]; cnt=0; merge_sort(1,n); cout<<cnt<<endl; } return 0; }
|
顺便附上归并排序的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <iostream> using namespace std; int n,cnt; const int maxn=100005; long long a[maxn]; long long b[maxn]; void merge_sort(int l,int r) { if(r>l) { int mid=(l+r)/2; int i=l; int p=l,q=mid+1; merge_sort(l,mid); merge_sort(mid+1,r); while(p<=mid||q<=r) { if(q>r||(p<=mid&&a[p]<=a[q])) b[i++] = a[p++]; else { b[i++]=a[q++]; cnt+=mid-p+1; } } for(i=l;i<=r;i++) a[i]=b[i]; } } int main() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; merge_sort(1,n); for(int i=1;i<=n;i++) { cout<<a[i]<<" "; } cout<<endl; return 0; }
|