เพื่อเติมเต็มคำตอบของ ngoaho91
วิธีที่ดีที่สุดในการแก้ปัญหานี้คือการใช้โครงสร้างข้อมูลกลุ่มต้นไม้ สิ่งนี้ช่วยให้คุณสามารถตอบแบบสอบถามใน O (log (n)) ซึ่งหมายถึงความซับซ้อนโดยรวมของอัลกอริทึมของคุณจะเป็น O (Q logn) โดยที่ Q คือจำนวนคิวรี หากคุณใช้อัลกอริทึมไร้เดียงสาความซับซ้อนทั้งหมดจะเป็น O (Q n) ซึ่งช้ากว่าอย่างเห็นได้ชัด
อย่างไรก็ตามมีข้อเสียเปรียบของการใช้เซกเมนต์ทรี ใช้หน่วยความจำมาก แต่หลายครั้งที่คุณสนใจเรื่องความจำน้อยกว่าความเร็ว
ฉันจะอธิบายสั้น ๆ อัลกอริทึมที่ใช้โดย DS นี้:
ทรีเซ็กเมนต์เป็นเพียงกรณีพิเศษของทรีการค้นหาแบบไบนารีซึ่งทุกโหนดเก็บค่าของช่วงที่ได้รับมอบหมาย โหนดรูทถูกกำหนดช่วง [0, n] เด็กด้านซ้ายถูกกำหนดช่วง [0, (0 + n) / 2] และเด็กด้านขวา [(0 + n) / 2 + 1, n] วิธีนี้ต้นไม้จะถูกสร้างขึ้น
สร้างต้นไม้ :
/*
A[] -> array of original values
tree[] -> Segment Tree Data Structure.
node -> the node we are actually in: remember left child is 2*node, right child is 2*node+1
a, b -> The limits of the actual array. This is used because we are dealing
with a recursive function.
*/
int tree[SIZE];
void build_tree(vector<int> A, int node, int a, int b) {
if (a == b) { // We get to a simple element
tree[node] = A[a]; // This node stores the only value
}
else {
int leftChild, rightChild, middle;
leftChild = 2*node;
rightChild = 2*node+1; // Or leftChild+1
middle = (a+b) / 2;
build_tree(A, leftChild, a, middle); // Recursively build the tree in the left child
build_tree(A, rightChild, middle+1, b); // Recursively build the tree in the right child
tree[node] = max(tree[leftChild], tree[rightChild]); // The Value of the actual node,
//is the max of both of the children.
}
}
ต้นไม้แบบสอบถาม
int query(int node, int a, int b, int p, int q) {
if (b < p || a > q) // The actual range is outside this range
return -INF; // Return a negative big number. Can you figure out why?
else if (p >= a && b >= q) // Query inside the range
return tree[node];
int l, r, m;
l = 2*node;
r = l+1;
m = (a+b) / 2;
return max(query(l, a, m, p, q), query(r, m+1, b, p, q)); // Return the max of querying both children.
}
หากคุณต้องการคำอธิบายเพิ่มเติมเพียงแจ้งให้เราทราบ
BTW, Segment Tree ยังรองรับการอัพเดทองค์ประกอบเดี่ยวหรือช่วงขององค์ประกอบใน O (log n)