HDU 4911 Inversion
考点:归并排序
思路:这题呀比赛的时候忘了知道可以用归并排序算出逆序数,但是忘了归并排序的实质了,然后不会做……
因为看到题上说是相邻的两个数才能交换的时候,感觉归并排序好像不是得要相邻的呀,然后就这样晕……刚才重新看了才发现,归并就是相邻的交换的,正好是用来求逆序数的,唉……真的是做这个归并排序比赛就来了……真好!
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<queue> #include<set> #include<cmath> #include<limits> #include<bitset> #define mem(a,b) memset(a,b,sizeof(a)) #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define INF 510010 #define maxn 100010 using namespace std; typedef long long ll; typedef unsigned long long ull; ll sum; void merge(ll A[], int p, int q, int r) { int n1 = q - p + 1; int n2 = r - q; ll *L=new ll[n1 + 1]; ll *R=new ll[n2 + 1]; for(int i = 0; i < n1; i++) L[i] = A[p + i]; for(int i = 0; i < n2; i++) R[i] = A[q + 1 + i]; L[n1] = numeric_limits<ll>::max(); R[n2] = numeric_limits<ll>::max(); int i = 0, j = 0; for(int k = p; k <= r; k++) { if(L[i] <= R[j]) A[k] = L[i],i++; else A[k] = R[j],j++,sum += n1 - i; } delete []L; delete []R; } void mergesort(ll A[], int l, int r) { if(l >= r) return ; int q = (l + r) / 2; mergesort(A, l, q); mergesort(A, q + 1, r); merge(A, l, q, r); } ll a[100005]; int main() { //freopen("test.txt","r",stdin); int n,k,i; while(~scanf("%d%d",&n,&k)) { sum=0; for(i=0; i<n; i++) scanf("%d",a+i); mergesort(a,0,n-1); if(sum>k) printf("%I64d\n",sum-k); else puts("0"); } return 0; }
原文:http://blog.csdn.net/u011466175/article/details/38391609