hdu 1394 Minimum Inversion Number 线段树求逆序数

#include<bits/stdc++.h>
using namespace std;

const int N=5000+5;
int a[N];

struct Tree
{
    int left,right,sum;
}tree[4*N+10];


void build(int id,int l,int r)
{
    tree[id].left=l;
    tree[id].right=r;
    if (l==r)
        tree[id].sum=a[l];
    else
    {
        int mid=(l+r)/2;
        build(id*2,l,mid);
        build(id*2+1,mid+1,r);
        tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
    }
}

void update(int id,int pos,int val)
{
    if (tree[id].left==tree[id].right)
        tree[id].sum=val;
    else
    {
        int mid=(tree[id].left+tree[id].right)/2;
        if (pos<=mid) update(id*2,pos,val);
        else update(id*2+1,pos,val);
        tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
    }
}

int query(int id,int l,int r)
{
    if (tree[id].left==l&&tree[id].right==r)
        return tree[id].sum;
    else
    {
        int mid=(tree[id].left+tree[id].right)/2;
        if (r<=mid) return query(id*2,l,r);
        else if (l>mid) return query(id*2+1,l,r);
        else return query(id*2,l,mid)+query(id*2+1,mid+1,r);
    }
}

int main()
{
    int n,i,x,ans,tmp;
    while(~scanf("%d",&n))
    {
        ans=0xfffffff;
        memset(a,0,sizeof(a));
        build(1,1,n);
        tmp=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            a[i]++;
        }
        for(i=n;i>=1;i--)
        {
            tmp+=query(1,1,a[i]);
            update(1,a[i],1);
        }
        ans=tmp;
        for(i=1;i<=n;i++)
        {
            tmp-=a[i]-1;
            tmp+=n-a[i];
            ans=min(ans,tmp);
        }
        printf("%d\n",ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。http://xiang578.top/

posted @ 2015-09-28 19:40  xryz  阅读(122)  评论(0编辑  收藏  举报