[树状数组/离散化]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
注意:
- 给定数组的长度不会超过
50000
。 - 输入数组中的所有数字都在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; } };