Untuk melengkapi jawaban ngoaho91.
Cara terbaik untuk mengatasi masalah ini adalah menggunakan struktur data Segment Tree. Ini memungkinkan Anda untuk menjawab pertanyaan seperti di O (log (n)), itu berarti kompleksitas total algoritma Anda akan menjadi O (Q logn) di mana Q adalah jumlah permintaan. Jika Anda menggunakan algoritma naif, kompleksitas totalnya adalah O (Q n) yang jelas lebih lambat.
Namun, ada kelemahan dari penggunaan Pohon Segmen. Membutuhkan banyak memori, tetapi seringkali Anda tidak terlalu peduli dengan memori daripada kecepatan.
Saya akan menjelaskan secara singkat algoritma yang digunakan oleh DS ini:
Pohon segmen hanya kasus khusus dari Pohon Pencarian Biner, di mana setiap node memegang nilai rentang itu ditugaskan. Simpul root, diberikan kisaran [0, n]. Anak kiri diberi kisaran [0, (0 + n) / 2] dan anak kanan [(0 + n) / 2 + 1, n]. Dengan cara ini pohon akan dibangun.
Buat Pohon :
/*
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.
}
}
Pohon Permintaan
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.
}
Jika Anda perlu penjelasan lebih lanjut, beri tahu saya.
BTW, Segment Tree juga mendukung pembaruan elemen tunggal atau serangkaian elemen di O (log n)