poj 2299 歸併求逆序數
阿新 • • 發佈:2018-12-24
題意:給出一些數,然後求這串數字的逆序數,也就是從這個狀態到升序狀態的最小步數。
思路:歸併排序,同時累加子問題的逆序數。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[500010]; __int64 ans; int Left[250005] , Right[250005]; void merge(int p , int q , int r) { int n1 , n2; n1 = q - p + 1; n2 = r - q; int i , j , k; for(i = 0 ; i < n1 ; i ++) Left[i] = a[p+i]; Left[n1] = 0xfffffff; for(i = 0 ; i < n2 ; i ++) Right[i] = a[q+1+i]; Right[n2] = 0xfffffff; i = j = 0; for(k = p ; k <= r ; k ++) { if(Left[i]<=Right[j]) { a[k] = Left[i]; i++; } else { a[k] = Right[j]; j++; ans += n1 - i; //統計子問題的逆序數 } } } void mergesort(int p , int r) { int q; if(p < r) { q = (p + r)/2; mergesort(p , q); mergesort(q+1 , r); merge(p , q , r); } } int main() { int n , i; while(~scanf("%d",&n)) { if(n == 0) break; for(i = 0 ; i < n ; i ++) scanf("%d",&a[i]); ans = 0; mergesort(0 , n-1); printf("%I64d\n",ans); } return 0; }