1. 程式人生 > >POJ2299 Ultra-QuickSort

POJ2299 Ultra-QuickSort

代碼 while include 個數 變換 else 之前 col max

題目鏈接:https://vjudge.net/problem/POJ-2299

題目大意:

  求數列中逆序對的個數。

知識點:  歸並排序

解題思路:

  對於數列中的每一個逆序對,它們之間早晚都需要一次鄰位變換,因此答案即為數列中逆序對的個數。

  我們用歸並排序求逆序對個數:對於左右兩個已經排好序的子區間,在合並之前先用一種\(O(n)\)的方式計算出母區間中逆序對的個數,具體方式見代碼。

AC代碼:

 1 #include <cstdio>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 500000
+5; 5 ll a[maxn],temp[maxn]; 6 ll ans; 7 void MergeSort(int l,int r){ 8 if(l==r) return; 9 int m=(l+r)>>1; 10 MergeSort(l,m); MergeSort(m+1,r); 11 for(int i=m,j=r;i>=l&&j>=m+1;){//計算逆序對個數 12 if(a[i]>a[j]){ 13 ans+=(j-m); 14 i--;
15 } 16 else j--; 17 } 18 for(int i=l,j=m+1,ind=0;i<=m||j<=r;ind++){ 19 if(i>m) temp[ind]=a[j++]; 20 else if(j>r) temp[ind]=a[i++]; 21 else if(a[i]<a[j]) temp[ind]=a[i++]; 22 else if(a[j]<a[i]) temp[ind]=a[j++]; 23 }
24 for(int i=l,j=0;i<=r;i++,j++) a[i]=temp[j]; 25 } 26 int main(){ 27 int n; 28 while(scanf("%d",&n)==1&&n){ 29 ans=0; 30 for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 31 MergeSort(1,n); 32 printf("%lld\n",ans); 33 } 34 return 0; 35 }

POJ2299 Ultra-QuickSort