Hướng giải của Đếm số nút trong khoảng
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.
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ả:
Hướng dẫn giải
Bài toán yêu cầu đếm số nút có giá trị trong khoảng \([L, R]\) trong BST. Ta có thể sử dụng phương pháp duyệt có điều kiện để bỏ qua các nhánh không cần thiết.
Các bước thực hiện:
- Xây dựng BST từ dãy đầu vào.
- Với mỗi truy vấn \((L, R)\), thực hiện đệ quy trên BST:
- Nếu nút hiện tại có giá trị nằm trong \([L, R]\), tăng biến đếm.
- Nếu giá trị nút lớn hơn \(L\), duyệt cây con trái.
- Nếu giá trị nút nhỏ hơn \(R\), duyệt cây con phải.
Độ phức tạp: \(O(Q \times N)\) trong trường hợp xấu nhất.
Mã nguồn C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int val;
Node *left, *right;
Node(int v) : val(v), left(nullptr), right(nullptr) {}
};
Node* insert(Node* root, int val) {
if (!root) return new Node(val);
if (val < root->val) root->left = insert(root->left, val);
else root->right = insert(root->right, val);
return root;
}
int countRange(Node* root, int L, int R) {
if (!root) return 0;
int cnt = (L <= root->val && root->val <= R) ? 1 : 0;
if (L < root->val) cnt += countRange(root->left, L, R);
if (R > root->val) cnt += countRange(root->right, L, R);
return cnt;
}
int main() {
int N, Q;
cin >> N >> Q;
Node* root = nullptr;
for (int i = 0; i < N; ++i) {
int a; cin >> a;
root = insert(root, a);
}
while (Q--) {
int L, R;
cin >> L >> R;
cout << countRange(root, L, R) << "\n";
}
return 0;
}
Nhận xét