मेरा मानना है कि सभी प्रश्नों के लिए लघुगणकीय समय साध्य है। मुख्य विचार एक अंतराल के पेड़ का उपयोग करना है, जहां पेड़ में प्रत्येक नोड सूचकांकों के अंतराल से मेल खाती है। मैं डेटा संरचना के एक सरल संस्करण के साथ शुरू करके मुख्य विचारों का निर्माण करूँगा (जो अन्य कार्यों को प्राप्त कर सकते हैं और सेट कर सकते हैं लेकिन अन्य सुविधाओं का समर्थन करने के लिए) जोड़ सकते हैं।
एक साधारण योजना (समर्थन प्राप्त करें और सेट करें, लेकिन जोड़ या स्टैब नहीं)
कहते हैं कि एक अंतराल है फ्लैट यदि समारोह पर स्थिर है , यानी, अगर ।एफ [ ए , बी ] एफ ( ए ) = एफ ( ए + १ ) = ⋯ = एफ ( बी )[a,b]f[a,b]f(a)=f(a+1)=⋯=f(b)
हमारी सरल डेटा संरचना एक अंतराल वृक्ष होगी। दूसरे शब्दों में, हमारे पास एक बाइनरी ट्री है, जहां प्रत्येक नोड एक अंतराल (सूचकांकों) से मेल खाती है। हम पेड़ के प्रत्येक नोड में संबंधित अंतराल को संग्रहीत करेंगे । प्रत्येक पत्ती एक समतल अंतराल के अनुरूप होगी, और उन्हें व्यवस्थित किया जाएगा ताकि पत्तों को बाएं से दाएं पढ़ने से हमें लगातार समतल अंतराल का एक क्रम मिल सके जो कि असंतुष्ट हैं और जिनका मिलन । एक आंतरिक नोड के लिए अंतराल उसके दो बच्चों के अंतराल का मिलन होगा। इसके अलावा, प्रत्येक पत्ती नोड में हम मान संग्रहीत होगा समारोह के अंतराल परवी [ 1 , एन ] ℓ वी ( ℓ ) च मैं ( ℓ ) च चI(v)v[1,n]ℓV(ℓ)fI(ℓ)इस नोड के अनुसार (ध्यान दें कि यह अंतराल सपाट है, इसलिए अंतराल पर स्थिर है, इसलिए हम प्रत्येक पत्ती के नोड में एकल मान को संग्रहीत करते हैं)।ff
समान रूप से, आप कल्पना कर सकते हैं कि हम को सपाट अंतराल में विभाजित करते हैं, और फिर डेटा संरचना एक द्विआधारी खोज ट्री है जहां कुंजियाँ उन अंतरालों के बाएं छोर हैं। पत्तियों में कुछ स्थानों पर का मान होता है जहाँ स्थिर होता है।एफ एफ[1,n]ff
यह सुनिश्चित करने के लिए मानक तरीकों का उपयोग करें कि बाइनरी ट्री संतुलित रहता है, अर्थात, इसकी गहराई (जहाँ पेड़ में पत्तियों की वर्तमान संख्या को गिना जाता है)। बेशक, , इसलिए गहराई हमेशा । यह नीचे उपयोगी होगा।m m ≤ n O ( lg n )O(lgm)mm≤nO(lgn)
अब हम निम्न प्रकार से ऑपरेशन को सेट कर सकते हैं:
i O ( lg n ) O ( lg n )get(i) आसान है: हम उस पत्ती को खोजने के लिए पेड़ को पीछे छोड़ते हैं जिसका अंतराल होता है । यह मूल रूप से सिर्फ एक द्विआधारी खोज पेड़ का पता लगाने है। चूंकि गहराई , इसलिए चलने का समय ।iO(lgn)O(lgn)
set([a,b],y) पेचीदा है। यह इस तरह काम करता है:
सबसे पहले, हम पत्ती अंतराल लगता है युक्त ; अगर , तो हम इस पत्ती के अंतराल को दो अंतराल और (इस प्रकार इस पत्ती के नोड को एक आंतरिक नोड में बदलते हैं और दो बच्चों को पेश करते हैं)।एक एक 0 < एक [ एक 0 , एक - 1 ] [ एक , ख 0 ][a0,b0]aa0<a[a0,a−1][a,b0]
अगला, हम पत्ती अंतराल युक्त ; अगर , हम इस पत्ती के अंतराल को दो अंतरालों और (इस प्रकार इस पत्ती के नोड को आंतरिक नोड में बदलकर दो बच्चों को पेश करते हैं)।बी बी < बी १ [ ए १ , बी ] [ बी + १ , बी १ ][a1,b1]bb<b1[a1,b][b+1,b1]
इस बिंदु पर, मैं दावा करता हूं कि अंतराल को पेड़ में नोड्स के कुछ सबसेट के अनुरूप अंतराल के असंतुष्ट संघ के रूप में व्यक्त किया जा सकता है । तो, उन नोड्स के सभी वंशों को हटा दें (उन्हें पत्तियों में बदलना) और उन नोड्स में संग्रहीत मान को सेट करें ।ओ ( एलजी एन ) ओ ( एलजी एन ) वाई[a,b]O(lgn)O(lgn)y
अंत में, जब से हमने पेड़ के आकार को संशोधित किया है, हम पेड़ को फिर से संतुलित करने के लिए (पेड़ को संतुलित रखने के लिए किसी भी मानक तकनीक का उपयोग करके) किसी भी आवश्यक घुमाव का प्रदर्शन करेंगे।
चूंकि इस ऑपरेशन में नोड्स पर कुछ सरल ऑपरेशन शामिल हैं (और नोड्स का वह सेट समय में आसानी से पाया जा सकता है ), इस ऑपरेशन का कुल समय ।O ( lg n ) O ( lg n )O(lgn)O(lgn)O(lgn)
इससे पता चलता है कि हम समय प्रति ऑपरेशन में प्राप्त और सेट दोनों ऑपरेशन का समर्थन कर सकते हैं । वास्तव में, रनिंग टाइम को दिखाया जा सकता है , जहां अब तक किए गए सेट ऑपरेशन की संख्या है।O ( lg min ( n , s ) ) sO(lgn)O(lgmin(n,s))s
जोड़ने के लिए समर्थन जोड़ना
हम उपरोक्त डेटा संरचना को संशोधित कर सकते हैं ताकि यह ऐड ऑपरेशन का भी समर्थन कर सके। विशेष रूप से, पत्तियों में फ़ंक्शन के मूल्य को संग्रहीत करने के बजाय, इसे नोड्स के एक सेट में संग्रहीत संख्याओं के योग के रूप में दर्शाया जाएगा।
अधिक सटीक रूप से, इनपुट पर फ़ंक्शन का मान पुनर्प्राप्त करने योग्य होगा, क्योंकि पेड़ की जड़ से पत्ती तक के मार्ग पर नोड्स में संग्रहीत मानों का योग होता है जिनके अंतराल में होता है । प्रत्येक नोड हम एक मान संग्रहीत करेंगे ; यदि एक पत्ता के पूर्वजों का प्रतिनिधित्व (पत्ता ही सहित), तो कम से फंक्शन का मान हो जाएगा ।मैं मैं वी वी ( v ) वी 0 , वी 1 , ... , वी कश्मीर वी कश्मीर मैं ( v कश्मीर ) वी ( वी 0 ) + ⋯ + वी ( v कश्मीर )f(i)iivV(v)v0,v1,…,vkvkI(vk)V(v0)+⋯+V(vk)
ऊपर वर्णित तकनीकों के एक संस्करण का उपयोग करके प्राप्त और सेट ऑपरेशन का समर्थन करना आसान है। मूल रूप से, जैसा कि हम पेड़ को नीचे की ओर ले जाते हैं, हम मानों के चलने के योग पर नज़र रखते हैं, ताकि प्रत्येक नोड जो कि ट्रैवर्सल विज़िट के लिए है, हम रूट से तक नोड्स के मानों का योग ज्ञात करेंगे । एक बार जब हम ऐसा करते हैं, तो ऊपर वर्णित वर्णित और सेट के कार्यान्वयन के लिए सरल समायोजन पर्याप्त होगा।एक्सxx
और अब हम कुशलता से समर्थन कर सकते हैं । सबसे पहले, हम अंतराल के रूप में अंतराल को व्यक्त करते हैं जो पेड़ में नोड्स के कुछ सेट के समान है बाएं एंडपॉइंट पर एक नोड को विभाजित करते हुए और दाएं समापन बिंदु पर) ), जैसा कि सेट ऑपरेशन के चरणों 1-3 में किया जाता है। अब, हम बस उन नोड्स में संग्रहीत मूल्य में जोड़ते हैं। (हम उनके वंशजों को नहीं हटाते हैं।)[ एक , ख ] हे ( एलजी n ) हे ( एलजी n ) δ हे ( एलजी n )add([a,b],δ)[a,b]O(lgn)O(lgn)δO(lgn)
यह प्रति ऑपरेशन समय में, प्राप्त करने, सेट करने और जोड़ने का समर्थन करने का एक तरीका प्रदान करता है । वास्तव में, आपरेशन प्रति चलने का समय है जहां मायने रखता है सेट के संचालन की संख्या से अधिक जोड़ने के संचालन की संख्या।O ( lg min ( n , s ) ) sO(lgn)O(lgmin(n,s))s
छुरा संचालन में सहायक
छुरा घोंपना क्वेरी का समर्थन करने के लिए सबसे चुनौतीपूर्ण है। मूल विचार निम्नलिखित अतिरिक्त आवेग को संरक्षित करने के लिए उपरोक्त डेटा संरचना को संशोधित करना होगा:
(*) अंतराल जो प्रत्येक पत्ती अनुरूप होता है, एक अधिकतम समतल अंतराल होता है।ℓI(ℓ)ℓ
यहाँ मैं कहना है कि एक अंतराल है अधिक से अधिक फ्लैट अंतराल अगर (i) सपाट है, और (ii) कोई युक्त अंतराल सपाट है (दूसरे शब्दों में, सभी के लिए संतोषजनक , या तो या सपाट नहीं है)।[ एक , ख ] [ एक , ख ] एक ' , ख ' 1 ≤ एक ' ≤ एक ≤ ख ≤ ख ' ≤ n [ एक ' , ख ' ] = [ एक , ख ] [ एक ' , बी ′ ][a,b][a,b][a,b]a′,b′1≤a′≤a≤b≤b′≤n[a′,b′]=[a,b][a′,b′]
यह स्टैब ऑपरेशन को लागू करना आसान बनाता है:
- istab(i) उस पत्ती को ढूँढता है जिसके अंतराल में समाहित है , और फिर उस अंतराल को वापस करता है।i
हालांकि, अब हमें सेट को संशोधित करना होगा और इनवेरिएंट (*) को बनाए रखने के लिए ऑपरेशन जोड़ना होगा। हर बार जब हम दो भागों में विभाजित एक पत्ता, हम अपरिवर्तनीय उल्लंघन कर सकते हैं, तो पत्ता-अंतराल के कुछ आसन्न जोड़ी समारोह का एक ही मूल्य है । सौभाग्य से, प्रत्येक सेट / ऐड ऑपरेशन में अधिकतम 4 नए पत्ती अंतराल शामिल हैं। इसके अलावा, प्रत्येक नए अंतराल के लिए, पत्ती अंतराल को तुरंत बाईं और दाईं ओर खोजना आसान है। इसलिए, हम बता सकते हैं कि क्या हमलावर का उल्लंघन किया गया था; यदि यह था, तो हम आसन्न अंतराल को विलय कर देते हैं जहां का समान मूल्य है। सौभाग्य से, दो आसन्न अंतरालों को विलय करने से कैस्केडिंग परिवर्तनों को ट्रिगर नहीं किया जाता है (इसलिए हमें यह जांचने की आवश्यकता नहीं है कि क्या विलय ने इनवेरियन के अतिरिक्त उल्लंघन शुरू किए होंगे)। कुल मिलाकर, इसमें जांच शामिल हैf 12 = O ( 1 ) O ( lg n )ff12=O(1)अंतराल के जोड़े और संभवतः उन्हें विलय करना। अंत में, चूंकि एक विलय से पेड़ का आकार बदल जाता है, अगर यह संतुलन-अपरिवर्तकों का उल्लंघन करता है, तो पेड़ को संतुलित रखने के लिए किसी भी आवश्यक घुमाव का प्रदर्शन करें (बाइनरी पेड़ों को संतुलित रखने के लिए मानक तकनीकों का पालन करें)। कुल में, यह में सेट / परिचालनों को जोड़ने के लिए अतिरिक्त काम करता है।O(lgn)
इस प्रकार, यह अंतिम डेटा संरचना सभी चार ऑपरेशनों का समर्थन करती है, और प्रत्येक ऑपरेशन के लिए चलने का समय । एक अधिक सटीक अनुमान प्रति ऑपरेशन समय है, जहां सेट की संख्या गिनता है और संचालन जोड़ता है।O ( lg min ( n , s ) ) sO(lgn)O(lgmin(n,s))s
विचारों का विभाजन
काजी, यह एक बहुत ही जटिल योजना थी। मुझे आशा है कि मैंने कोई गलती नहीं की। कृपया इस समाधान पर भरोसा करने से पहले मेरे काम को ध्यान से देखें।
add
के उप-केंद्रों की संख्या में रैखिक होगा ; क्या आपने अतिरिक्त एकता " " नोड्स के साथ एक शानदार पेड़ के बारे में सोचा है , आलसी? + δ