求逆序对数
-
总时间限制:
- 500ms 内存限制:
- 65536kB
-
描述
-
对于一个长度为N的整数序列A,满足i < j 且 Ai > Aj.的数对(i,j)称为整数序列A的一个逆序
<j<=n且ai><j<=n且ai><j<=n且ai><j<=n且ai>请求出整数序列A的所有逆序对个数
输入
-
输入包含多组测试数据,每组测试数据有两行
第一行为整数N(1 <= N <= 20000),当输入0时结束
第二行为N个整数,表示长为N的整数序列
输出
- 每组数据对应一行,输出逆序对的个数 样例输入
-
5 1 2 3 4 5 5 5 4 3 2 1 1 1 0
样例输出
-
0 10 0
-
-
tips:没有给明整数范围,也没说整数是否可以为非正。离散化吧
-
#include<iostream> #include<cstring> #include<utility> #include<vector> #include<cstdio> #include<algorithm> using namespace std; const int maxn=110000; typedef pair<int,int>pr; int sum[maxn<<2]; vector<pr>v; void pushup(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void build(int rt,int l,int r) { if(l==r){ sum[rt]=0; return; } int m=(l+r)>>1; build(rt<<1,l,m); build(rt<<1|1,m+1,r); pushup(rt); } void update(int x,int rt,int l,int r) { if(l==r){ sum[rt]++; return; } int m=(l+r)>>1; if(x<=m)update(x,rt<<1,l,m); else update(x,rt<<1|1,m+1,r); pushup(rt); } int query(int rt,int l,int r,int ll,int rr) { if(ll<=l&&rr>=r){ return sum[rt]; } int ret=0; int m=(l+r)>>1; if(ll<=m)ret+=query(rt<<1,l,m,ll,rr); if(rr>m)ret+=query(rt<<1|1,m+1,r,ll,rr); return ret; } int main() { int n; while(scanf("%d",&n),n) { //build(1,1,maxn); memset(sum,0,sizeof(sum)); v.clear(); for(int i=1;i<=n;i++) { int x;scanf("%d",&x); v.push_back(make_pair(x,i)); } stable_sort(v.begin(),v.end()); int ans=0; for(int i=0;i<v.size();i++) { update(v[i].second,1,1,maxn); ans+=query(1,1,maxn,v[i].second+1,maxn); } cout<<ans<<endl; } return 0; }