UltraQuickSort(超快速排序)

题目大意:给出一些数,用最小的交换相邻两个数,使得为正序,求最小交换次数

解决:可以用归并排序,由于在士兵杀敌系列中已经用过了,所以为了练练何为树状数组中的离散化,再用树状数组做了一遍

/*
本题思路,首先将范围在0 ≤ a[i] ≤ 999,999,999之间的点压缩到0- 500,000之间,
然后统计每个数之前所有比这个数小的 */ #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int n; struct node { int id; int val; }; const int N=500005; node num[N]; int a[N]; __int64 c[N]; bool cmp(const node &a,const node &b) { return a.val > b.val; } int lowbit(int x) { return x&(-x); } void updata(int pos,int inc) { for(int i=pos;i<=n;i+=lowbit(i)) c[i]+=inc; } __int64 sum(int x) { __int64 sum=0; for(int i=x;i>0;i-=lowbit(i)) sum+=c[i]; return sum; } int main() { while(scanf("%d",&n),n) { int i; for(i=1;i<=n;i++) { scanf("%d",&num[i].val); num[i].id=i; } sort(num+1,num+n+1,cmp); a[num[1].id]=1; for(i=2;i<=n;i++) if(num[i].val==num[i-1].val)a[num[i].id]=a[num[i-1].id]; else a[num[i].id]=i; //以上过程为离散化 __int64 Count=0; memset(c,0,sizeof(c)); for(i=1;i<=n;i++) {//统计a[i]之前比a[i]小的个数和 Count+=sum(a[i]-1); updata(a[i],1); } printf("%I64d\n",Count); } system("pause"); return 0; }

原文地址:https://www.cnblogs.com/hpustudent/p/2149324.html