POJ 2299 Ultra QuickSort <树状数组+离散化 / 归并排序>

来源:互联网 发布:java教程pdf完整版 编辑:程序博客网 时间:2024/06/01 10:32

题目:传送门。


分析:求序列的逆序数。用树状数组和归并排序都可以做,因为a[i]可能有999,999,999这么大,所以先对数据进行离散。


代码:

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;struct DATA{int val,posi;};const int MAXN=5e5+5;int n,a[MAXN],bit[MAXN];DATA data[MAXN];bool comp(DATA& a,DATA& b){return a.val<b.val;}void add(int i){while(i<=n){bit[i]+=1;i+=i&-i;}}int sum(int i){int _sum=0;while(i>0){_sum+=bit[i];i-=i&-i;}return _sum;}void solve(){__int64 ans=0;for(int i=1;i<=n;++i) bit[i]=0;for(int i=1;i<=n;++i){add(a[i]);ans+=i-sum(a[i]);}cout<<ans<<endl;}int main(){ios::sync_with_stdio(false);while(cin>>n,n){for(int i=1;i<=n;++i){cin>>data[i].val;data[i].posi=i;}sort(data+1,data+1+n,comp);for(int i=1;i<=n;++i){a[data[i].posi]=i;}solve();}return 0;} 

#include <iostream>#include <cstdio>using namespace std;const int MAXN=5e5+5;int A[MAXN],T[MAXN];__int64 ans;void Merg_Sort(int l,int r){if(l>=r-1) return ;int mid=l+(r-l)/2;Merg_Sort(l,mid);Merg_Sort(mid,r);int p=l,q=mid,i=l;while(p<mid||q<r){if(q>=r||(p<mid&&A[p]<=A[q])) T[i++]=A[p++];else{if(p<mid) ans+=mid-p;T[i++]=A[q++];}}for(int i=l;i<r;++i){A[i]=T[i];}}int main(){ios::sync_with_stdio(false);int n;while(cin>>n,n){ans=0;for(int i=0;i<n;++i){cin>>A[i];}Merg_Sort(0,n);cout<<ans<<endl;}return 0;}


0 0