对每个元素统计它前面值为它二倍的元素个数。统计前/后比它大/小个数用BIT,思路和315. Count of Smaller Numbers After Self一样。BIT能在元素可mutable的要求下以O(lgN)时间求presum,树的每个index对应元素值,里头存的是元素值当前的个数。因此只要根据元素值大小对应到BIT的index,然后对任意想查的元素找到对应的index后,就能以O(lgN)算出所有index和index前(比它大/小)的和(总个数)。这道题比315在查index上麻烦了点,从后往前遍历的话,需要找不超过当前元素值1/2的最大值,用二分法,再用值查对应的index。
/*
* @lc app=leetcode id=493 lang=cpp
*
* [493] Reverse Pairs
*
* https://leetcode.com/problems/reverse-pairs/description/
*
* algorithms
* Hard (23.52%)
* Likes: 613
* Dislikes: 91
* Total Accepted: 28.5K
* Total Submissions: 120.1K
* Testcase Example: '[1,3,2,3,1]'
*
* Given an array nums, we call (i, j) an important reverse pair if i < j and
* nums[i] > 2*nums[j].
*
* You need to return the number of important reverse pairs in the given
* array.
*
* Example1:
*
* Input: [1,3,2,3,1]
* Output: 2
*
*
* Example2:
*
* Input: [2,4,3,5,1]
* Output: 3
*
*
* Note:
*
* The length of the given array will not exceed 50,000.
* All the numbers in the input array are in the range of 32-bit integer.
*
*
*/
// @lc code=start
class Solution {
public:
class BIT {
public:
vector<int> sums;
BIT(const int N): sums(N + 1, 0) {};
static inline int lowbit(int x) {return x & (-x);}
void update(int i, int delta) {
while (i < sums.size()) {
sums[i] += delta;
i += lowbit(i);
}
}
int query(int i) const {
int sum = 0;
while (i > 0) {
sum += sums[i];
i -= lowbit(i);
}
return sum;
}
};
int reversePairs(vector<int>& nums) {
const int N = nums.size();
vector<int> v(nums);
sort(v.begin(), v.end());
unordered_map<int, int> indices;
for (int i = 0; i < N; ++i) {
indices[v[i]] = i + 1;
}
int res = 0;
BIT tree(N);
for (int i = N - 1; i >= 0; --i) {
res += tree.query(lower_bound(v.begin(), v.end(), nums[i] / 2.0) - v.begin());
tree.update(indices[nums[i]], 1);
}
return res;
}
};
// @lc code=end