剑指Offer——JZ35.数组中的逆序对【树状数组】

本文介绍了一种使用树状数组解决逆序对计算的高效算法。通过离散化处理,确保了编号逆序对与原始数据的一致性。代码示例展示了如何在C++中实现这一算法,包括添加元素、获取前缀和以及计算逆序对数量。

题目传送门


在这里插入图片描述


题解

  • 非常简单的树状数组应用
  • 需要离散化,离散后编号的的逆序对和之前相同

AC-Code

class Solution {
#define lowbit(x) (x&-x)
private:
    const int mod = 1e9 + 7;
    const static int maxn = 2e5 + 7;
    struct NODE {
        int val, pos;
        NODE(int v = 0, int p = 0):val(v), pos(p) {}
    }a[maxn];
    int c[maxn] = {0};
    
public:
    int InversePairs(vector<int> data) {
        int ans = 0;
        for(int i = 0; i < data.size(); ++i) {
            a[i + 1].pos = i + 1;
            a[i + 1].val = data[i];
        }
        sort(a + 1, a + 1 + data.size(), [](NODE a, NODE b)-> bool { return a.val < b.val; });
        for(int i = 1; i <= data.size(); ++i) {
            add(a[i].pos, 1);
            ans = (ans + i - getsum(a[i].pos)) % mod;
        }
        return ans;
    }
    void add(int i, int x) {
        while(i < maxn) {
            c[i] += x;
            i += lowbit(i);
        }
    }
    int getsum(int i) {
        int res = 0;
        while(i > 0) {
            res += c[i];
            i -= lowbit(i);
        }
        return res;
    }
 #undef lowbit(x)
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值