hdu 4911 Inversion (分治 归并排序 求逆序数)
题意:给n个数,求交换k次相邻的数之后的最小的逆序数对。
用分治的方法,以前在poj上做过这种题,昨天比赛的时候忘了。。。。
下面的归并排序还是以前的模板。
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 #define LL __int64 8 const int maxn = 100000+10; 9 using namespace std; 10 int n; 11 LL sum, a[maxn], b[maxn]; 12 13 void merge_sort(LL *A, int x, int y, LL *T) 14 { 15 if(y-x>1) 16 { 17 int m=x+(y-x)/2; 18 int p=x, q=m, i=x; 19 merge_sort(A,x,m,T); 20 merge_sort(A,m,y,T); 21 while(p<m || q<y) 22 { 23 if(q>=y ||(p<m && A[p] <= A[q])) 24 T[i++] = A[p++]; 25 else 26 { 27 T[i++] = A[q++]; 28 sum+=m-p; 29 } 30 31 } 32 for(i=x; i<y; i++) 33 A[i] = T[i]; 34 } 35 }; 36 int main() 37 { 38 int k, i; 39 while(~scanf("%d%d", &n, &k)) 40 { 41 sum = 0; 42 memset(b, 0, sizeof(b)); 43 for(i = 0; i < n; i++) 44 scanf("%I64d", &a[i]); 45 merge_sort(a, 0, n, b); 46 if(sum-k<0) sum = k; 47 printf("%I64d\n", sum-k); 48 } 49 return 0; 50 }