树状数组_poj_2299_Ultra-QuickSort
2016-07-11 21:49
691 查看
题目链接
题意:求逆序对。
方法:树状数组+离散化
这道题数据量比较大,直接开数组是不行的,所以采取离散化的办法,其实也就是弄一个映射关系而已。
具体思想就是排好序,建立映射关系,然后开一个一样大的数组,按照原来的输入顺序在其映射的位置加1 (加的时候用树状数组的更新函数),然后用区间查询函数统计它前面有多少个数已经输入了(即区间求和),在这个数前面的都是比它小的数,所以算一下就知道有多少比它大的数在它前面了,即逆序对求出。
题意:求逆序对。
方法:树状数组+离散化
这道题数据量比较大,直接开数组是不行的,所以采取离散化的办法,其实也就是弄一个映射关系而已。
具体思想就是排好序,建立映射关系,然后开一个一样大的数组,按照原来的输入顺序在其映射的位置加1 (加的时候用树状数组的更新函数),然后用区间查询函数统计它前面有多少个数已经输入了(即区间求和),在这个数前面的都是比它小的数,所以算一下就知道有多少比它大的数在它前面了,即逆序对求出。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=500000+50; int a[maxn],ref[maxn]; int N; struct node{int v,pos;}nod[maxn]; bool cmp(node x,node y){ return x.v<y.v; } void Add(int k){ while(k<=N){ a[k]+=1; k+=k&-k; } } int query(int x){ int ans=0; while(x){ ans+=a[x]; x-=x&-x; } return ans; } int main(){ while(cin>>N&&N){ for(int i=1;i<=N;i++){ scanf("%d",&nod[i].v); nod[i].pos=i; } memset(a,0,sizeof(a)); sort(nod+1,nod+1+N,cmp); for(int i=1;i<=N;i++)ref[nod[i].pos]=i; long long ans=0; for(int i=1;i<=N;i++){ Add(ref[i]); ans+=i-query(ref[i]); } cout<<ans<<endl; } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- 逆序对
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- POJ1050 最大子矩阵和