hdu-1394(线段树)
Posted 2018zxy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-1394(线段树)相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394
思路:建立一个空线段树,求出逆序数,(逆序数性质:交换两个相邻数,逆序数+1或-1, 交换两个不相邻数a, b, 逆序数+=两者间大于a的个数-两者间小于a的个数)
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int maxn = 50050; int a[maxn*4],n,b[maxn*4]; void build(int k,int l,int r) { b[k]=0; if(l==r) return ; int mid=(l+r)/2; build(k*2,l,mid); build(k*2+1,mid+1,r); } void update(int k,int l,int r,int x,int pos) { if(l==r) { b[k]+=x; return ; } int mid=(l+r)/2; if(pos<=mid) update(k*2,l,mid,x,pos); else update(k*2+1,mid+1,r,x,pos); b[k]=b[k*2]+b[k*2+1]; } int query(int k,int l,int r,int x,int y) { if(x<=l&&y>=r) return b[k]; int mid=(l+r)/2; if(y<=mid) return query(k*2,l,mid,x,y); if(x>mid) return query(k*2+1,mid+1,r,x,y); return query(k*2,l,mid,x,y)+query(k*2+1,mid+1,r,x,y); } int main(void) { int i,sum,tmp; while(~scanf("%d",&n)) { build(1,1,n); sum=0; for(i=1;i<=n;i++) { scanf("%d",&a[i]); sum+=query(1,1,n,a[i]+1,n); update(1,1,n,1,a[i]+1); } tmp=sum; for(i=1;i<=n;i++) { sum+=(n-1-a[i]-a[i]); if(tmp>sum) tmp=sum; } printf("%d ",tmp); } return 0; }
以上是关于hdu-1394(线段树)的主要内容,如果未能解决你的问题,请参考以下文章