hdu 1394

来源:互联网 发布:matlab求矩阵多少行 编辑:程序博客网 时间:2024/06/15 22:51

线段树 求 逆序数。。

初始化线段树 为 0 ,对输入的 n 个数据 一次判断 ,假设 输入 x ,则 更新 线段树前 先 询问 区间 x+1 到 n 之间 的 sum 值

即 有 多少个 比 x大 的数,然后 更新 x 值 为 1

求出 逆序数之后 ,利用 递推可 算出 全排列 的 最小 逆序数 ,举个 例子

101 3 6 9 0 8 5 7 4 2
分别求出 比 该 数 大的数的 个数
8 6 3 0 9 1 4 2 5 7
则 下一个排列 的逆序数 只要 把当前排列 的逆序数 + 比 第一个数 大的数 的个数 - 比 第一个数小 的数个数 即可


//============================================================================// Name        : HH.cpp// Author      : lxw// Version     :// Copyright   : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================#include <iostream>using namespace std;#define lson u<<1#define rson u<<1|1const int maxn=5005;int dat[maxn];struct Node{int lef,rig,sum;}T[maxn<<2];void Build(int u,int l,int r){T[u].lef=l;T[u].rig=r;if(l==r){T[u].sum=0;return;}int mid=(l+r)>>1;Build(lson,l,mid);Build(rson,mid+1,r);T[u].sum=T[lson].sum+T[rson].sum;}void Update(int u,int index,int val){if(T[u].lef==index&&T[u].rig==index){T[u].sum+=val;return;}else {if(index<=T[lson].rig)Update(lson,index,val);else Update(rson,index,val);T[u].sum=T[lson].sum+T[rson].sum;}}int Query(int u,int from,int to){if(T[u].lef==from&&T[u].rig==to){return T[u].sum;}if(to<=T[lson].rig)return Query(lson,from,to);if(from>=T[rson].lef)return Query(rson,from,to);return Query(lson,from,T[lson].rig)+Query(rson,T[rson].lef,to);}int main() {int n,i;while(scanf("%d",&n)==1){Build(1,1,n);int cnt=0;for(i=1;i<=n;i++){scanf("%d",&dat[i]);cnt+=Query(1,dat[i]+1,n);Update(1,dat[i],1);}int ans=cnt;for(i=1;i<=n;i++){cnt+=-dat[i]+n-1-dat[i];//printf("%d\n",cnt);if(ans>cnt)ans=cnt;}printf("%d\n",ans);}return 0;}


原创粉丝点击