Minimum Inversion Number

来源:互联网 发布:4 2网络协议转换器 编辑:程序博客网 时间:2024/05/23 00:07

http://acm.hdu.edu.cn/showproblem.php?pid=1394


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=5005;int sum[maxn<<2];void PushUP(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){sum[rt]=0;if(l==r) return;int m=(l+r)>>1;build(l,m,rt<<1);build(m+1,r,rt<<1|1);}void update(int p,int l,int r,int rt){if(l==r){sum[rt]=1;//表示出现标记; return ;}int m=(l+r)>>1;if(p<=m) update(p,l,m,rt<<1);else update(p,m+1,r,rt<<1|1);PushUP(rt);}//单点更新,读到该点,该点变为1;int query(int L,int R,int l,int r,int rt){if(L<=l&&R>=r) return sum[rt];int m=(l+r)>>1;int ret=0;if(L<=m) ret+=query(L,R,l,m,rt<<1);if(R>m) ret+=query(L,R,m+1,r,rt<<1|1);return ret;}//更新之前,进行询问,看看有几个比该点要大的点已读入,统计一下; int x[maxn];int main(int argc, char *argv[]){int n;while(~scanf("%d",&n)){build(1,n,1);int sum=0;for(int i=1;i<=n;i++){scanf("%d",&x[i]);sum+=query(x[i]+1,n,1,n,1);//printf("%d\n\n",query(x[i]+1,n,1,n,1));update(x[i]+1,1,n,1);}int ret=sum;for(int i=1;i<=n;i++){sum+=n-x[i]-x[i]-1;ret=min(ret,sum);}printf("%d\n",ret);}return 0;}


0 0