HDOJ-1394 Minimum Inversion Number

这道题先求出整个数列(长度为n)的逆序对个数,方法是对于数m,累加线段树中(m, n-1)中已插入数的个数,再更新…..求出的逆序对个数为sum.在循环数列,把每个数调到最后面,假设数为M,则此时sum += n-1-2*m;

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

#define maxn 5005

struct node{
    int l, r, s;
}T[maxn<<2];
int num[maxn];

void Build(int n, int l, int r)
{
    T[n].l = l;
    T[n].r = r;
    T[n].s = 0;

    if(l == r)
     return ;
    int mid = (l + r) / 2;
    Build(n<<1, l, mid);
    Build(n<<1|1, mid+1, r);
}
void Update(int n, int s)
{
    if(T[n].l == T[n].r)
    {
        T[n].s++;
        return ;
    }

    int mid = (T[n].l + T[n].r) / 2;
    if(s <= mid)
        Update(n<<1, s);
    else
       Update(n<<1|1, s);
    T[n].s = T[n<<1].s + T[n<<1|1].s;

}
void Query(int n, int l, int r, int &s)
{
    if(T[n].l == l && T[n].r == r)
    {
        s += T[n].s;
        return ;
    }
    int mid = (T[n].l + T[n].r) / 2;

    if(r <= mid)
         Query(n<<1, l, r, s);
    else if(l > mid)
            Query(n<<1|1, l, r, s);
    else{
        Query(n<<1, l, mid, s);
        Query(n<<1|1, mid+1, r, s);
    }
}
int main()
{
    //freopen("in.txt", "r", stdin);
    int n;

    while(cin >> n)
    {
        int sum = 0;
        Build(1, 0, n-1);

        for(int i = 0; i < n; i++)
        {
            int b;

            scanf("%d", num+i);
            b = 0;
            Query(1, num[i], n-1, b);
            sum += b; 
            Update(1, num[i]);
        }
        int mins = sum;
        for(int i = 0; i < n-1; i++)
        {
            int m = n - 1 - 2 * num[i];

            sum += m;
            mins = min(mins, sum);
        }
        cout << mins << endl;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值