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, सेगमेंट ट्री O (लॉग एन) में एकल तत्व या तत्वों की एक श्रृंखला के अद्यतन का समर्थन करता है