Hướng giải của Đếm Số Cặp Nghịch Thế


Nhớ rằng hướng dẫn giải này chỉ nên sử dụng khi bế tắc, và tuyệt đối không nên sao chép mã nguồn kèm theo. Hãy tôn trọng tác giả bài tập và người viết hướng dẫn giải.
Nộp mã nguồn lời giải chính thức trước khi giải bài tập đó có thể khiến bạn bị ban.

Tác giả: kienadmin

Hướng dẫn giải

Bài toán đếm số cặp nghịch thế \(A[i] > A[j]\) với \(i < j\). Chúng ta có thể giải quyết bằng Segment Tree:

  1. Ban đầu dựng một cây Segment Tree trống quản lý tần số xuất hiện của các số trong khoảng \([1, N]\) (tất cả bằng \(0\)).
  2. Duyệt phần tử \(A[i]\) từ trái qua phải:
    • Số lượng số lớn hơn \(A[i]\) đã xuất hiện chính là truy vấn tổng trên khoảng \([A[i] + 1, N]\). Ta cộng giá trị này vào kết quả.
    • Thực hiện cập nhật tăng tần số xuất hiện của số \(A[i]\) thêm 1 trên cây Segment Tree.

Độ phức tạp thời gian: \(O(N \log N)\).

Mã nguồn C++ mẫu

#include <bits/stdc++.h>
using namespace std;

struct SegTree {
    int n; vector<int> tree;
    SegTree(int size) { n = size; tree.assign(4 * n, 0); }
    void update(int node, int start, int end, int pos, int val) {
        if(start == end) { tree[node] += val; return; }
        int mid = (start + end)/2;
        if(pos <= mid) update(2*node, start, mid, pos, val);
        else update(2*node+1, mid+1, end, pos, val);
        tree[node] = tree[2*node] + tree[2*node+1];
    }
    int query(int node, int start, int end, int l, int r) {
        if(r < start || end < l) return 0;
        if(l <= start && end <= r) return tree[node];
        int mid = (start + end)/2;
        return query(2*node, start, mid, l, r) + query(2*node+1, mid+1, end, l, r);
    }
};

int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL);
    int n; if(!(cin >> n)) return 0;
    vector<int> a(n);
    SegTree st(n + 1);
    long long inv_count = 0;
    for(int i=0;i<n;i++){
        cin >> a[i];
        inv_count += st.query(1, 1, n, a[i] + 1, n);
        st.update(1, 1, n, a[i], 1);
    }
    cout << inv_count << "\n";
}

Nhận xét

Không có ý kiến tại thời điểm này.