|
52 | 52 |
|
53 | 53 | 解决方案是直接遍历数组,每个位置先求出 `query(a[i])`,然后再修改树状数组 `update(a[i], 1)` 即可。当数的范围比较大时,需要进行离散化,即先进行去重并排序,然后对每个数字进行编号。
|
54 | 54 |
|
| 55 | +**方法三:线段树** |
| 56 | + |
55 | 57 | <!-- tabs:start -->
|
56 | 58 |
|
57 | 59 | ### **Python3**
|
@@ -139,6 +141,72 @@ class Solution:
|
139 | 141 | return ans
|
140 | 142 | ```
|
141 | 143 |
|
| 144 | +线段树: |
| 145 | + |
| 146 | +```python |
| 147 | +class Node: |
| 148 | + def __init__(self): |
| 149 | + self.l = 0 |
| 150 | + self.r = 0 |
| 151 | + self.v = 0 |
| 152 | + |
| 153 | +class SegmentTree: |
| 154 | + def __init__(self, n): |
| 155 | + self.tr = [Node() for _ in range(4 * n)] |
| 156 | + self.build(1, 1, n) |
| 157 | + |
| 158 | + def build(self, u, l, r): |
| 159 | + self.tr[u].l = l |
| 160 | + self.tr[u].r = r |
| 161 | + if l == r: |
| 162 | + return |
| 163 | + mid = (l + r) >> 1 |
| 164 | + self.build(u << 1, l, mid) |
| 165 | + self.build(u << 1 | 1, mid + 1, r) |
| 166 | + |
| 167 | + def modify(self, u, x, v): |
| 168 | + if self.tr[u].l == x and self.tr[u].r == x: |
| 169 | + self.tr[u].v += 1 |
| 170 | + return |
| 171 | + mid = (self.tr[u].l + self.tr[u].r) >> 1 |
| 172 | + if x <= mid: |
| 173 | + self.modify(u << 1, x, v) |
| 174 | + else: |
| 175 | + self.modify(u << 1 | 1, x, v) |
| 176 | + self.pushup(u) |
| 177 | + |
| 178 | + def pushup(self, u): |
| 179 | + self.tr[u].v = self.tr[u << 1].v + self.tr[u << 1 | 1].v |
| 180 | + |
| 181 | + def query(self, u, l, r): |
| 182 | + if self.tr[u].l >= l and self.tr[u].r <= r: |
| 183 | + return self.tr[u].v |
| 184 | + mid = (self.tr[u].l + self.tr[u].r) >> 1 |
| 185 | + v = 0 |
| 186 | + if l <= mid: |
| 187 | + v += self.query(u << 1, l, r) |
| 188 | + if r > mid: |
| 189 | + v += self.query(u << 1 | 1, l, r) |
| 190 | + return v |
| 191 | + |
| 192 | + |
| 193 | +class Solution: |
| 194 | + def reversePairs(self, nums: List[int]) -> int: |
| 195 | + s = set() |
| 196 | + for num in nums: |
| 197 | + s.add(num) |
| 198 | + s.add(num * 2) |
| 199 | + alls = sorted(s) |
| 200 | + m = {v: i for i, v in enumerate(alls, 1)} |
| 201 | + tree = SegmentTree(len(m)) |
| 202 | + ans = 0 |
| 203 | + for v in nums[::-1]: |
| 204 | + x = m[v] |
| 205 | + ans += tree.query(1, 1, x - 1) |
| 206 | + tree.modify(1, m[v * 2], 1) |
| 207 | + return ans |
| 208 | +``` |
| 209 | + |
142 | 210 | ### **Java**
|
143 | 211 |
|
144 | 212 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
@@ -248,6 +316,95 @@ class BinaryIndexedTree {
|
248 | 316 | }
|
249 | 317 | ```
|
250 | 318 |
|
| 319 | +线段树: |
| 320 | + |
| 321 | +```java |
| 322 | +class Solution { |
| 323 | + public int reversePairs(int[] nums) { |
| 324 | + TreeSet<Long> ts = new TreeSet<>(); |
| 325 | + for (int num : nums) { |
| 326 | + ts.add((long) num); |
| 327 | + ts.add((long) num * 2); |
| 328 | + } |
| 329 | + Map<Long, Integer> m = new HashMap<>(); |
| 330 | + int idx = 0; |
| 331 | + for (long num : ts) { |
| 332 | + m.put(num, ++idx); |
| 333 | + } |
| 334 | + SegmentTree tree = new SegmentTree(m.size()); |
| 335 | + int ans = 0; |
| 336 | + for (int i = nums.length - 1; i >= 0; --i) { |
| 337 | + int x = m.get((long) nums[i]); |
| 338 | + ans += tree.query(1, 1, x - 1); |
| 339 | + tree.modify(1, m.get((long) nums[i] * 2), 1); |
| 340 | + } |
| 341 | + return ans; |
| 342 | + } |
| 343 | +} |
| 344 | + |
| 345 | +class Node { |
| 346 | + int l; |
| 347 | + int r; |
| 348 | + int v; |
| 349 | +} |
| 350 | + |
| 351 | +class SegmentTree { |
| 352 | + private Node[] tr; |
| 353 | + |
| 354 | + public SegmentTree(int n) { |
| 355 | + tr = new Node[4 * n]; |
| 356 | + for (int i = 0; i < tr.length; ++i) { |
| 357 | + tr[i] = new Node(); |
| 358 | + } |
| 359 | + build(1, 1, n); |
| 360 | + } |
| 361 | + |
| 362 | + public void build(int u, int l, int r) { |
| 363 | + tr[u].l = l; |
| 364 | + tr[u].r = r; |
| 365 | + if (l == r) { |
| 366 | + return; |
| 367 | + } |
| 368 | + int mid = (l + r) >> 1; |
| 369 | + build(u << 1, l, mid); |
| 370 | + build(u << 1 | 1, mid + 1, r); |
| 371 | + } |
| 372 | + |
| 373 | + public void modify(int u, int x, int v) { |
| 374 | + if (tr[u].l == x && tr[u].r == x) { |
| 375 | + tr[u].v += v; |
| 376 | + return; |
| 377 | + } |
| 378 | + int mid = (tr[u].l + tr[u].r) >> 1; |
| 379 | + if (x <= mid) { |
| 380 | + modify(u << 1, x, v); |
| 381 | + } else { |
| 382 | + modify(u << 1 | 1, x, v); |
| 383 | + } |
| 384 | + pushup(u); |
| 385 | + } |
| 386 | + |
| 387 | + public void pushup(int u) { |
| 388 | + tr[u].v = tr[u << 1].v + tr[u << 1 | 1].v; |
| 389 | + } |
| 390 | + |
| 391 | + public int query(int u, int l, int r) { |
| 392 | + if (tr[u].l >= l && tr[u].r <= r) { |
| 393 | + return tr[u].v; |
| 394 | + } |
| 395 | + int mid = (tr[u].l + tr[u].r) >> 1; |
| 396 | + int v = 0; |
| 397 | + if (l <= mid) { |
| 398 | + v += query(u << 1, l, r); |
| 399 | + } |
| 400 | + if (r > mid) { |
| 401 | + v += query(u << 1 | 1, l, r); |
| 402 | + } |
| 403 | + return v; |
| 404 | + } |
| 405 | +} |
| 406 | +``` |
| 407 | + |
251 | 408 | ### **C++**
|
252 | 409 |
|
253 | 410 | 归并排序:
|
@@ -351,6 +508,85 @@ public:
|
351 | 508 | };
|
352 | 509 | ```
|
353 | 510 |
|
| 511 | +线段树: |
| 512 | + |
| 513 | +```cpp |
| 514 | +class Node { |
| 515 | +public: |
| 516 | + int l; |
| 517 | + int r; |
| 518 | + int v; |
| 519 | +}; |
| 520 | + |
| 521 | +class SegmentTree { |
| 522 | +public: |
| 523 | + vector<Node*> tr; |
| 524 | + |
| 525 | + SegmentTree(int n) { |
| 526 | + tr.resize(4 * n); |
| 527 | + for (int i = 0; i < tr.size(); ++i) tr[i] = new Node(); |
| 528 | + build(1, 1, n); |
| 529 | + } |
| 530 | + |
| 531 | + void build(int u, int l, int r) { |
| 532 | + tr[u]->l = l; |
| 533 | + tr[u]->r = r; |
| 534 | + if (l == r) return; |
| 535 | + int mid = (l + r) >> 1; |
| 536 | + build(u << 1, l, mid); |
| 537 | + build(u << 1 | 1, mid + 1, r); |
| 538 | + } |
| 539 | + |
| 540 | + void modify(int u, int x, int v) { |
| 541 | + if (tr[u]->l == x && tr[u]->r == x) |
| 542 | + { |
| 543 | + tr[u]->v += v; |
| 544 | + return; |
| 545 | + } |
| 546 | + int mid = (tr[u]->l + tr[u]->r) >> 1; |
| 547 | + if (x <= mid) modify(u << 1, x, v); |
| 548 | + else modify(u << 1 | 1, x, v); |
| 549 | + pushup(u); |
| 550 | + } |
| 551 | + |
| 552 | + void pushup(int u) { |
| 553 | + tr[u]->v = tr[u << 1]->v + tr[u << 1 | 1]->v; |
| 554 | + } |
| 555 | + |
| 556 | + int query(int u, int l, int r) { |
| 557 | + if (tr[u]->l >= l && tr[u]->r <= r) return tr[u]->v; |
| 558 | + int mid = (tr[u]->l + tr[u]->r) >> 1; |
| 559 | + int v = 0; |
| 560 | + if (l <= mid) v = query(u << 1, l, r); |
| 561 | + if (r > mid) v += query(u << 1 | 1, l, r); |
| 562 | + return v; |
| 563 | + } |
| 564 | +}; |
| 565 | + |
| 566 | +class Solution { |
| 567 | +public: |
| 568 | + int reversePairs(vector<int>& nums) { |
| 569 | + set<long long> s; |
| 570 | + for (int num : nums) |
| 571 | + { |
| 572 | + s.insert(num); |
| 573 | + s.insert(num * 2ll); |
| 574 | + } |
| 575 | + unordered_map<long long, int> m; |
| 576 | + int idx = 0; |
| 577 | + for (long long num : s) m[num] = ++idx; |
| 578 | + SegmentTree* tree = new SegmentTree(m.size()); |
| 579 | + int ans = 0; |
| 580 | + for (int i = nums.size() - 1; i >= 0; --i) |
| 581 | + { |
| 582 | + ans += tree->query(1, 1, m[nums[i]] - 1); |
| 583 | + tree->modify(1, m[nums[i] * 2ll], 1); |
| 584 | + } |
| 585 | + return ans; |
| 586 | + } |
| 587 | +}; |
| 588 | +``` |
| 589 | +
|
354 | 590 | ### **Go**
|
355 | 591 |
|
356 | 592 | 归并排序:
|
|
0 commit comments