题目链接:http://poj.org/problem?id=2299
用了树状数组,求逆序数。读入这些数,每读一个数就update一次,看一下它前面比它小的已出现过的有多少个sum(),然后用当前的位置-当前的sum(),就可以得到当前逆序对数了,加起来就得到总的逆序对数。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 500010 int n,c[N],reflect[N]; struct Node { int val; int pos; } node[N]; bool cmp(Node a,Node b) { return a.val<b.val; } int lowbit(int x) { return x & (-x); } void update(int i) { while(i<=n) { c[i]+=1; i+=lowbit(i); } } int sum(int i) { int s=0; while(i>0) { s+=c[i]; i-=lowbit(i); } return s; } int main() { int i,j; while(scanf("%d",&n),n) { for(i=1; i<=n; i++) { scanf("%d",&node[i].val); node[i].pos=i; } sort(node+1,node+n+1,cmp); for(i=1; i<=n; i++) { c[i]=0; reflect[node[i].pos]=i; } long long int ans=0; for(i=1; i<=n; i++) { update(reflect[i]); ans += i-sum(reflect[i]); } printf("%lld\n",ans); } return 0; }
POJ 2299 Ultra-QuickSort,布布扣,bubuko.com
原文:http://www.cnblogs.com/man1304010109/p/3596995.html