[树状数组/离散化]leetcode 493. 翻转对

493. 翻转对

给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对

你需要返回给定数组中的重要翻转对的数量。

示例 1:

输入: [1,3,2,3,1]
输出: 2

示例 2:

输入: [2,4,3,5,1]
输出: 3

注意:

  1. 给定数组的长度不会超过50000
  2. 输入数组中的所有数字都在32位整数的表示范围内。

竟然是个hard题,秒掉

typedef long long ll;
class Solution {
public:
    struct LSH {
        vector <ll> vec;
        void push (ll num) {
            vec.push_back(num);
        }
        ll getPos(ll num) {
            return lower_bound(vec.begin(), vec.end(), num) - vec.begin() + 1;
        }
        void proc() {
            sort(vec.begin(), vec.end());
            vec.erase(unique(vec.begin(), vec.end()), vec.end());
        }
    };

    struct BIT {
        BIT (ll num) {
            max = num + 10;
        }
        unordered_map <ll, ll> bit;
        ll max;
        void add (ll pos, ll val) {
            for (; pos <= max; pos += (pos & -pos)) {
                bit[pos] += val;
            }
        }
        ll ask(ll pos) {
            ll ret = 0;
            for ( ;pos > 0; pos -= (pos & -pos)) {
                ret += bit[pos];
            }
            return ret;
        }
    };

    int reversePairs(vector<int>& nums) {
        reverse(nums.begin(), nums.end());
        int ans = 0;
        LSH lsh;
        for (auto &x : nums) {
            lsh.push(x);
            lsh.push(ll(x) * 2);
        }
        lsh.proc();
        BIT bit(lsh.vec.size());
        for (auto &x: nums) {
            ans += bit.ask(lsh.getPos(x) - 1);
            bit.add(lsh.getPos(ll(x) * 2), 1);
        }
        return ans;
    }
};

 

posted @ 2020-11-28 12:07  张浦  阅读(193)  评论(0编辑  收藏  举报