逆序对(树状数组)
对于数组A,A[i]的逆序对数量为i之前比它大的数的个数。如果已经知道A中的最大值max,当我们顺序的去求A[i]的逆序对的数量的时候,其实就是找此时A中i之前A[i]到max的数有多少个。当然,对于求区间内的事情,树状数组和线段树是最为擅长的。一下代码仅仅考虑A中的元素为正整数的情况,如果数太大或者有负数或者有double的情形需要先离散化处理。
#include <vector> #include <iostream> #include <algorithm> #include <cmath> using namespace std; class TreeArray { public: TreeArray(int size) { tree_array_.resize(size + 1, 0); } int Sum(int pos) { int sum = 0; while (pos > 0) { sum += tree_array_[pos]; pos -= LowBit(pos); } return sum; } void Update(int pos, int increase) { while (pos < tree_array_.size()) { tree_array_[pos] += increase; pos += LowBit(pos); } } private: int LowBit(int pos) { return pos & (-pos); } private: vector<int> tree_array_; }; int GetReversePairNum(const vector<int>& arr, int max) { TreeArray tree_arr(max); int num = 0; for (int i = 0; i < arr.size(); ++i) { num += tree_arr.Sum(max) - tree_arr.Sum(arr[i]); tree_arr.Update(arr[i], 1); } return num; } int main() { int a[] = {3,3,2,1,11,13,2,1,7,8}; // int a[] = {3,3,2}; vector<int> arr; arr.assign(a, a + sizeof(a) / sizeof(int)); int max_num = 0; for (int i = 0; i < arr.size(); ++i) { max_num = max(arr[i], max_num); } cout << GetReversePairNum(arr, max_num) << endl; return 1; }
Passion, patience, perseverance, keep it and move on.

浙公网安备 33010602011771号