http://ac.jobdu.com/problem.php?cid=1039&pid=19
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
先离散化
在统计后面比前面大的有几个保存到all
逆序对队 n*(n-1)/2-all 注意long long
View Code
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; long long N; long long tree[200009]; struct data { long long no; long long real; long long pai; }ss[200009]; long long lowbit(long long x) { return x&(-x); } void updata(long long x,long long c) { long long i; for(i=x;i<=N;i+=lowbit(i)) { tree[i]+=c; } } long long getsum(long long x) { long long i; long long temp=0; for(i=x;i>=1;i-=lowbit(i)) { temp+=tree[i]; } return temp; } long long cmp(data a,data b) { if(a.real==b.real) return a.no<b.no; return a.real<b.real; } long long cmp2(data a,data b) { return a.no<b.no; } int main() { long long n; while(scanf("%lld",&n)!=EOF){ N=n; long long i,j; for(i=1;i<=n;i++){ scanf("%lld",&ss[i].real); ss[i].no=i; } sort(&ss[1],&ss[1+n],cmp); long long add=1; ss[1].pai=1; for(i=2;i<=n;i++){ if(ss[i].real==ss[i-1].real) ss[i].pai=ss[i-1].pai; else ss[i].pai=ss[i-1].pai+1; } sort(&ss[1],&ss[1+n],cmp2); //for(i=1;i<=n;i++){ // printf("%d ",ss[i].pai); //} for(i=0;i<=n;i++) { tree[i]=0; } long long all=0; updata(ss[1].pai,1); for(i=2;i<=n;i++) { all+=getsum(ss[i].pai); updata(ss[i].pai,1); } long long temp=n*(n-1)/2-all; printf("%lld\n",temp); } return 0; }