hdu 1394

题目

询问每一个数中比这个数大的有多少个,然后进行更新。

接着是若把一个数移动最后,则逆序数是减少a,增加n-a-1.

代码如下:

#include
#include
using namespace std;
#define maxn 5005
#define rson l,m,rt<<1
#define lson m+1,r,rt<<1|1

struct Tree
{
    int l,r,num;
}tree[maxn<<2];

int num[5005];

void PushUp(int rt)
{
    tree[rt].num=tree[rt<<1].num+tree[rt<<1|1].num;
}

void build(int l,int r,int rt)
{
    tree[rt].l=l;
    tree[rt].r=r;
    tree[rt].num=0;
    if(l==r){
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}

void update(int pos,int rt)
{
    int l,r;
    l=tree[rt].l;
    r=tree[rt].r;
    tree[rt].num++;
    if(l==r) return ;

    int m=(l+r)>>1;
    if(pos<=m) update(pos,rt<<1);
    else update(pos,rt<<1|1);
}

int query(int x,int y,int rt)
{
    int l,r;
    l=tree[rt].l;
    r=tree[rt].r;
    if(l==x&&y==r)
    {
        return tree[rt].num;
    }

    int m=(l+r)>>1,ans=0;
    if(y<=m) ans+=query(x,y,rt<<1);
    else if(x>m) ans+=query(x,y,rt<<1|1);
    else {
        ans+=query(x,m,rt<<1);
        ans+=query(m+1,y,rt<<1|1);
    }
    return ans;
}

int main()
 {
     int n;
     while(~scanf("%d",&n))
     {
         int i;
         int sum=0;
         build(1,n,1);
         for(i=1;i<=n;i++)
         {
             scanf("%d",&num[i]);
             sum+=query(num[i]+1,n,1);
             update(num[i]+1,1);
         }
         int res=sum;
         for(i=1;i<=n;i++)
         {
             sum=sum-num[i]+(n-num[i]-1);
             if(res>sum)
                 res=sum;
         }
         printf("%d\n",res);
     }
     return 0;
 }


你可能感兴趣的:(ACM-数据结构,线段树&&树状数组)