बाइनरी अनुक्रमित पेड़ों के साथ रेंज अपडेट + रेंज क्वेरी


10

मैं यह समझने की कोशिश कर रहा हूं कि द्विआधारी अनुक्रमित पेड़ (फेनविक पेड़) को रेंज क्वेरी और रेंज अपडेट दोनों को संभालने के लिए कैसे संशोधित किया जा सकता है।

मुझे निम्नलिखित स्रोत मिले:

http://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/ http://programmingcontests.quora.com/Tutorial-Range-Updates-in-Fenwick-Tree http : //apps.topcoder.com/forums/ मॉड्यूल = थ्रेड और threadid = 756,271 और शुरू = 0 और एम सी = 4 # 1,579,597

लेकिन उन सभी के माध्यम से पढ़ने के बाद भी मैं यह नहीं समझ सका कि दूसरे बाइनरी इंडेक्स वाले पेड़ का उद्देश्य क्या है या यह क्या करता है।

क्या कोई मुझे समझा सकता है कि इनको संभालने के लिए बाइनरी इंडेक्स ट्री को कैसे संशोधित किया जाता है?

जवाबों:


9

मान लीजिए कि आपके पास एक खाली सरणी है:

0  0  0  0  0  0  0  0  0  0  (array)
0  0  0  0  0  0  0  0  0  0  (cumulative sums)

और आप +5 की सीमा अद्यतन करना चाहते थे [3..7]:

0  0  0  5  5  5  5  5  0  0  (array)
0  0  0  5 10 15 20 25 25 25  (desired cumulative sums)

आप 2 बाइनरी अनुक्रमित पेड़ों का उपयोग करके वांछित संचयी रकम कैसे स्टोर कर सकते हैं?

चाल दो द्विआधारी अनुक्रमित पेड़ों, बीआईटी 1 और बीआईटी 2 का उपयोग करना है, जहां उनकी सामग्री से संचयी राशि की गणना की जाती है। इस उदाहरण में, यहाँ हम दो पेड़ों में क्या संग्रहित करेंगे:

0   0   0   5   5   5   5   5   0   0  (BIT1)
0   0   0  10  10  10  10  10 -25 -25  (BIT2)

खोजने के लिए sum[i], आप इसकी गणना करते हैं:

sum[i] = BIT1[i] * i - BIT2[i]

उदाहरण के लिए:

sum[2] = 0*2 - 0 = 0
sum[3] = 5*3 - 10 = 5
sum[4] = 5*4 - 10 = 10
...
sum[7] = 5*7 - 10 = 25
sum[8] = 0*8 - (-25) = 25
sum[9] = 0*9 - (-25) = 25

पिछली श्रेणी के अपडेट के लिए वांछित BIT1 और BIT2 मान प्राप्त करने के लिए, हम 3 रेंज अपडेट करते हैं:

  • BIT1 के लिए हमें 3.5 से लेकर सूचकांकों तक +5 की एक श्रेणी अपडेट करने की आवश्यकता है।

  • हमें BIT2 के लिए सूचकांकों के लिए 3.10 की एक सीमा अद्यतन करने की आवश्यकता है।

  • हमें BIT2 के लिए -25 से सूचकांक 8..9 तक की रेंज अपडेट करने की आवश्यकता है।

अब एक और परिवर्तन करते हैं। BIT1 और BIT2 के लिए ऊपर दिखाए गए मानों को संग्रहीत करने के बजाय, हम वास्तव में उनके संचयी रकमों को संग्रहीत करते हैं। इससे हम संचयी रकमों में 4 अपडेट करके ऊपर की 3 रेंज अपडेट कर सकते हैं:

BIT1sum[3] += 5
BIT1sum[8] -= 5
BIT2sum[3] += 10
BIT2sum[8] -= 35

सामान्य तौर पर, एक श्रेणी [i..j] में मान v जोड़ने के लिए एल्गोरिथ्म होगा:

BIT1sum[i]   += v
BIT1sum[j+1] -= v
BIT2sum[i]   += v * (i-1)
BIT2sum[j+1] -= v * j

जहाँ + = और - = सिंटैक्स का अर्थ है उस सूचकांक पर सकारात्मक या नकारात्मक मान के साथ BIT संचयी योग डेटा संरचना को अद्यतन करना। ध्यान दें कि जब आप किसी सूचकांक में BIT संचयी योग को अद्यतन करते हैं, तो यह उस सूचकांक के दाईं ओर सभी सूचकांकों को प्रभावित करता है। उदाहरण के लिए:

0 0 0 0 0 0 0 0 0 0 (original)

BITsum[3] += 5

0 0 0 5 5 5 5 5 5 5 (after updating [3])

BITsum[8] -= 5

0 0 0 5 5 5 5 5 0 0 (after updating [8])

फेनविक पेड़ एक द्विआधारी वृक्ष में रकम जमा करते हैं। ऊपर दिखाए गए अपडेट्स को Fenwick ट्री में करना आसान हैO(logn) समय।


BIT2 बनाने और फिर होने में आपकी प्रारंभिक प्रेरणा क्या थी sum[i] = BIT1[i] * i - BIT2[i]? यह काम करने लगता है लेकिन यह इतना मनमाना लगता है ... क्या अंतर्दृष्टि आपको इस पर आने की अनुमति देती है?
1110101001

3
वैसे मैंने इस एल्गोरिथ्म का आविष्कार नहीं किया है। मैंने इसे वैसे ही पढ़ा जैसे आपने किया। लेकिन ध्यान देने वाली एक बात यह है कि जब आप एक रेंज अपडेट जोड़ते हैं, तो आपके संचयी रकम बढ़ते क्रम (5, 10, 15, 20, ...) बन जाते हैं। BITs उस तरह बढ़ते क्रमों को संग्रहीत नहीं करते हैं। लेकिन अगर आप बीआईटी में एक स्थिर (5) स्टोर करते हैं, और इंडेक्स द्वारा बीआईटी मूल्य को गुणा करते हैं, तो आपको एक बढ़ता हुआ क्रम मिलता है जैसे आप चाहते हैं। हालांकि, आपको अनुक्रम की शुरुआत और अंत को ठीक करने की आवश्यकता है। वही दूसरा पेड़ है।
JS1

पूरी तरह से अच्छा है, लेकिन मुझे यह भ्रमित लगता है कि आपने लिखा है "बीआईटी 1 और बीआईटी 2 के लिए ऊपर दिखाए गए मूल्यों को संग्रहीत करने के बजाय, हम वास्तव में उनके संचयी योगों को संग्रहीत करते हैं" - मैं कहूंगा कि आप वास्तव में विपरीत कर रहे हैं, अर्थात, डेल्टा को संग्रहीत करना ।
j_random_hacker
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.