zoj 2386 || poj 2299 Ultra-QuickSort

我晕 ,这个我没有写题解么。。忘了。。

 

求逆序数。。。

 

白皮书上有,用的归并排序,今天又看了算导的归并排序,写了下,过了。

 

因为这个题在树状数组的分类下的,所以尝试用树状数组做。想了会。。。

 

因为数的范围很大,不过个数只有50W,所以就排下序,重新编数,这个据说叫离散化 = =。。。

 

编数之后,求这个数之前比这个数大的,不过用树状数组的话求比它小的值是比较容易的,那么就把数离散化的时候从大到小排序,然后求这个数之前比它小的即可。

 

归并排序

 

#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 500010 using namespace std; int a[MAX]; int tb[MAX/2],te[MAX/2]; long long sum; void Merger(int *a,int beg,int mid,int end) { int k; int n1 = mid - beg + 1; int n2 = end - mid; int i = 0,j = 0; for(k=beg; k<=mid; k++) tb[i++] = a[k]; tb[n1] = INT_MAX; for(k=mid+1; k<=end; k++) te[j++] = a[k]; te[n2] = INT_MAX; i = j = 0; for(k=beg; k<=end; k++) if( tb[i] <= te[j] ) a[k] = tb[i++]; else { sum += ( n1 - i ); a[k] = te[j++]; } } void Mergersort(int *a,int beg,int end) { if( beg < end ) { int mid = (beg+end)/2; Mergersort(a,beg,mid); Mergersort(a,mid+1,end); Merger(a,beg,mid,end); } } int main() { int n,i; while( ~scanf("%d",&n) && n ) { sum = 0; for(i=0; i<n; i++) scanf("%d",&a[i]); Mergersort(a,0,n-1); printf("%lld/n",sum); } return 0; }  

 

 

离散化+树状数组(看着可专业是吧。。。为嘛排个序就叫离散化啊。。。)

 

#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 500010 using namespace std; typedef struct ARR{ int n,ind; }ARR; ARR a[MAX]; long long sum; int c[MAX],aa[MAX]; bool cmp( ARR a, ARR b ) { return a.n > b.n; } int Lowbit(int x) { return x & (-x); } void Updata(int x) { while( x < MAX ) { c[x]++; x += Lowbit(x); } } int Getsum(int x) { int sum = 0; while( x > 0 ) { sum += c[x]; x -= Lowbit(x); } return sum; } int main() { int n,i,tmp; while( ~scanf("%d",&n) && n ) { sum = 0ll; memset(c,0,sizeof(c)); for(i=1; i<=n; i++) { scanf("%d",&a[i].n); a[i].ind = i; } sort(a+1,a+n+1,cmp); int p = 1; aa[ a[1].ind ] = p; tmp = a[1].n; for(i=1; i<=n; i++) if( a[i].n == tmp ) aa[ a[i].ind ] = p; else { tmp = a[i].n; p++; aa[ a[i].ind ] = p; } for(i=1; i<=n; i++) { sum += Getsum(aa[i]); Updata(aa[i]); } printf("%lld/n",sum); } return 0; }  

你可能感兴趣的:(zoj 2386 || poj 2299 Ultra-QuickSort)