HDU 1394 - Minimum Inversion Number(树状数组求逆序数)

本文介绍了一种使用树状数组求解逆序数的方法,并提供了完整的AC代码实现。该方法无需离散化处理,适用于HDU 1394等逆序数相关题目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1394

题解:

利用树状数组搞一搞逆序数就好了,这题不需要离散化

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int tree[5005],LEN;
int lowbit(int i)
{
    return i&( -i);
}
void add(int k, int i)
{
    while(k <= LEN)
    {
        tree[k] += i;
        k += lowbit(k);
    }
}
int sum(int k)
{
    int re = 0;
    while(k > 0)
    {
        re += tree[k];
        k -= lowbit(k);
    }
    return re;
}
int main()
{
    int ans;
    int number[5005] = {0};
    while(cin >> LEN)
    {
        memset(tree,0,sizeof(tree));
        for(int i = 0; i < LEN; i++)
            scanf("%d", &number[i]);
        int ct1 = 0,ct2 = 0;
        for(int i = 0; i < LEN; i ++)
        {
            ct1 += sum(LEN - number[i]);//sum(LEN - number[i])即是number[i]的逆序数
            cout << sum(LEN - number[i]) << " ";
            add(LEN - number[i],1);//按从大到小的顺序加数排列,这样树状数组的前几项的和就是逆序数了
        }
        ans = ct1;
        cout << ans <<endl;
        //for(int i = 1; i <= LEN; i++)
          //  cout << sum(i) <<endl;
        for(int i = 0; i < LEN-1; i++)
        {
            ct2 = ct1;//新的逆序数 = 前一个逆序数
            add(LEN - number[i], -1);
            ct2 = ct2 + sum(LEN - number[i]) - number[i];//数学问题,sum2 = sum1 + 取出的数的逆序数 - 取出的数
            add(LEN - number[i], 1);
           // cout << ct2 <<endl;
            if(ans > ct2)
                ans = ct2;
            ct1 = ct2;//新的逆序数
        }
        printf("%d\n", ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值