POJ 2299 Ultra-QuickSort
做完这题长知识了,原来求逆序数可以用排序的交换次数来计算。
但仅限于稳定的排序,用快排这类不稳定的办不了。
下面是代码:
#include <stdio.h> #include <stdio.h> long long a[500005],temp[500005]; long long ans; void mergearray(int first, int mid, int last) { int i = first, j = mid + 1; int m = mid, n = last; int k = 0; while (i <= m && j <= n) { if (a[i] <= a[j]) { temp[k++] = a[i++]; } else { temp[k++] = a[j++]; ans+=mid - i +1; } } while (i <= m) { temp[k++] = a[i++]; } while (j <= n) { temp[k++] = a[j++]; } for (i = 0; i < k; i++) { a[first + i] = temp[i]; } } void mergesort(int first, int last) { if (first < last) { int mid = (first + last) / 2; mergesort(first, mid);//递归分解 mergesort(mid + 1, last);//递归分解 mergearray(first, mid, last);//合并 } } int main() { int n; while(scanf("%d",&n),n) { int i; for(i=0; i<n; i++) { scanf("%lld",&a[i]); } ans=0; mergesort(0,n-1); printf("%lld\n",ans); } return 0; }
这两天在学线段树,就用线段树写了一遍:
#include <stdio.h> #include <string.h> #include <stdlib.h> const int Max=500005; int node[Max<<2]; struct node1 { int num; int t; }num[Max]; void PushUp(int tr) { node[tr]=node[tr<<1]+node[tr<<1|1]; } int query(int L,int R,int l,int r,int tr) { if(L<=l&&r<=R)return node[tr]; int m=(l+r)>>1; int ans=0; if(L<=m)ans+=query(L,R,l,m,tr<<1); if(m<R)ans+=query(L,R,m+1,r,tr<<1|1); return ans; } void update(int p,int l,int r,int tr) { if(l==r) { node[tr]++; return; } int m=(l+r)>>1; if(p<=m)update(p,l,m,tr<<1); else update(p,m+1,r,tr<<1|1); PushUp(tr); } int cmp1(const void *a,const void *b) { struct node1 *aa=(struct node1 *)a; struct node1 *bb=(struct node1 *)b; return aa->num-bb->num; } int cmp2(const void *a,const void *b) { struct node1 *aa=(struct node1 *)a; struct node1 *bb=(struct node1 *)b; return aa->t-bb->t; } int main() { int n; while(scanf("%d",&n),n) { int a; long long ans=0; memset(node,0,sizeof(node)); for(int i=0;i<n;i++) { scanf("%d",&num[i].num); num[i].t=i; } qsort(num,n,sizeof(num[0]),cmp1); int min1=num[0].num,cnt=1; for(int i=0;i<n;i++) { if(num[i].num==min1) { num[i].num=cnt; } else { cnt++; min1=num[i].num; num[i].num=cnt; } } qsort(num,n,sizeof(num[0]),cmp2); for(int i=0;i<n;i++) { ans+=query(num[i].num,n,1,n,1); update(num[i].num,1,n,1); } printf("%lld\n",ans); } return 0; }