前言
欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
今天是七月集训第二十四天:线段树🔥🔥🔥🔥
一、练习题目
二、算法思路
- 1、剑指 Offer 51. 数组中的逆序对:🔥🔥🔥🔥这道题有很多种做法,这里利用线段树来做。
三、源码剖析
// 剑指 Offer 51. 数组中的逆序对
class Solution {
#define maxn 50010
vector<int> val;
int getIndex(int v) {
int l = 0, r = val.size() - 1;
while(l <= r) {
int mid = (l + r) >> 1;
if(v > val[mid]) {
l = mid + 1;
} else if(v < val[mid]) {
r = mid - 1;
} else {
return mid;
}
}
return -1;
}
int getValue(int idx) {
return val[idx];
}
struct SegTreeNode {
int sum;
}S[1<<17];
void build(int p, int l, int r) {
if(l == r) {
S[p].sum = 0;
return ;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p<<1|1, mid + 1, r);
}
void insert(int p, int l, int r, int pos) {
if(pos < l || pos > r) {
return ;
}
if(l == r) {
S[p].sum++;
return ;
}
int mid = (l + r) >> 1;
insert(p<<1, l, mid, pos);
insert(p<<1|1, mid+1, r, pos);
S[p].sum = S[p<<1].sum + S[p<<1|1].sum;
}
void query(int p, int l, int r, int ql, int qr, int& ans) {
if(qr < l || ql > r) {
return ;
}
if(ql <= l && r <= qr) {
ans += S[p].sum;
return ;
}
int mid = (l + r) >> 1;
query(p<<1, l, mid, ql, qr, ans);
query(p<<1|1, mid+1, r, ql, qr, ans);
}
public:
int reversePairs(vector<int>& nums) {
if(nums.size() == 0) {
return 0;
}
int i;
for(i = 0; i < nums.size(); ++i) {
val.push_back(nums[i]);
}
sort(val.begin(), val.end());
val.erase(unique(val.begin(), val.end()), val.end());
for(i = 0; i < nums.size(); ++i) {
nums[i] = getIndex(nums[i]);
}
int L = 0, R = nums.size() - 1;
int sum = 0;
for(i = R; i >= 0; --i) {
int ans = 0;
query(1, L, R, 0, nums[i] - 1, ans);
sum += ans;
insert(1, L, R, nums[i]);
}
return sum;
}
};
- 1、线段树