hdu 1394 最小逆序数(线段树版本)

来源:互联网 发布:java开源流程引擎源码 编辑:程序博客网 时间:2024/06/05 10:53

    从该数字num[i]就可以知道比它小的数有num[i]个,比它大的数有n-1-num[i]个.

         每次把num[i]放到最后时,summ = summ – num[i] + n-1-num[i];

#include<cstdio>#define Min(a,b) (a)<(b)?(a):(b)#define M 5005#define mid (l+r)>>1#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int sum[M<<2];void PushPlus(int rt){sum[rt] = sum[rt<<1] + sum[rt<<1|1];}void Updata(int p,int l,int r,int rt){if( l == r){sum[rt]++;return ;}int m=mid;if(p<=m)Updata(p,lson);elseUpdata(p,rson);PushPlus(rt);}void Bulid(int l,int r,int rt){sum[rt]=0;if(l == r)return ;int m=mid;Bulid(lson);Bulid(rson);//PushPlus(rt);反正都是0}int Query(int L,int R,int l,int r,int rt){if(L <= l && r <=R)return sum[rt];int m=mid,ans=0;if(L<=m)ans+=Query(L,R,lson);if(R>m)ans+=Query(L,R,rson);return ans;}int num[M];int main(){int n;while(~scanf("%d",&n)){Bulid(0,n-1,1);int summ=0;for(int i=0;i<n;i++){scanf("%d",&num[i]);summ+=Query(num[i],n-1,0,n-1,1);Updata(num[i],0,n-1,1);}int minsum=summ;for(int j=0;j<n;j++){summ+=n-num[j]-num[j]-1;minsum=Min(summ,minsum);}printf("%d\n",minsum);}return 0;}


原创粉丝点击