POJ--2299--Ultra-QuickSort
2013-06-28 21:57
274 查看
题目大意:给出一个数字序列,问冒泡排序需要交换数字的次数。
好题啊。。。看着1W多的通过数,以为是水题呢。
解题思路,求出序列中的逆序对数就是需要交换的次数,求逆序对数可以用树状数组求,但是题目给的数据范围略大,需要离散化原来的数据。
所以第一步:先对原来的数据排序,再离散数据,,用1-N 的数表示出各个数字的大小关系就可以了。
第二步:通过树状数组求出逆序对数即可。如果你不知道怎么通过树状数组求逆序对数,那么google一下吧
好题啊。。。看着1W多的通过数,以为是水题呢。
解题思路,求出序列中的逆序对数就是需要交换的次数,求逆序对数可以用树状数组求,但是题目给的数据范围略大,需要离散化原来的数据。
所以第一步:先对原来的数据排序,再离散数据,,用1-N 的数表示出各个数字的大小关系就可以了。
第二步:通过树状数组求出逆序对数即可。如果你不知道怎么通过树状数组求逆序对数,那么google一下吧
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define maxn 500200 #define lowbit(x) ((x)&(-(x))) using namespace std; struct Num { int num; int pos; bool operator<(const Num & a)const { return num<a.num; } }p[maxn]; int n,a[maxn],c[maxn]; void add(int num) { while(num<=n) { c[num]+=1; num+=lowbit(num); } } long long sum(int pos) { long long res=0; while(pos>0) { res+=c[pos]; pos-=lowbit(pos); } return res; } bool init() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&p[i].num); p[i].pos=i; } return n; } void solve() { sort(p,p+n); for(int i=0;i<n;i++) { a[p[i].pos]=i+1; } memset(c,0,sizeof(c)); long long ans=0; for(int i=0;i<n;i++) { add(a[i]); ans+=i-sum(a[i]-1); } cout<<ans<<endl; } int main() { while(init()) solve(); return 0; }
相关文章推荐
- 【原】 POJ 2299 Ultra-QuickSort 逆序数 解题报告
- POJ 2299 Ultra-QuickSort (树状数组 + 离散化)
- poj 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort (求逆序数:离散化+树状数组或者归并排序求逆序数)
- poj 2299 Ultra-QuickSort 【线段树求和(点更新)】
- POJ训练计划2299_Ultra-QuickSort(线段树/单点更新)
- POJ 2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort(归并排序)||(树状数组+离散化)
- poj 2299 Ultra-QuickSort 求逆序对,树状数组和归并排序
- poj--2299 Ultra-QuickSort(树状数组求逆序数)
- POJ2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort (求序列的逆序对数)
- poj_2299 Ultra-QuickSort
- poj 2299 Ultra-QuickSort 求逆序数 树状数组解法
- POJ 2299 Ultra-QuickSort
- [树状数组]POJ 2299 Ultra-QuickSort
- Ultra-QuickSort - POJ 2299 树状数组+离散化
- POJ 2299 Ultra-QuickSort
- POJ 2299 Ultra-QuickSort 树状数组
- POJ 2299 Ultra-QuickSort(树状数组求逆序数)