ฉันเชื่อว่าเวลาลอการิทึมสำหรับการค้นหาทั้งหมดทำได้ แนวคิดหลักคือการใช้ต้นไม้ช่วงเวลาที่แต่ละโหนดในต้นไม้สอดคล้องกับช่วงเวลาของดัชนี ฉันจะสร้างแนวคิดหลักโดยเริ่มจากโครงสร้างข้อมูลที่เรียบง่ายขึ้น (ซึ่งสามารถรองรับการตั้งค่า แต่ไม่ใช่การดำเนินการอื่น) จากนั้นเพิ่มคุณสมบัติเพื่อรองรับคุณสมบัติอื่น ๆ เช่นกัน
แบบแผนง่ายๆ (รองรับการรับและการตั้งค่า แต่ไม่เพิ่มหรือแทง)
บอกว่าช่วงเวลาเป็นแบนถ้าฟังก์ชันฉเป็นค่าคงที่บน[ , ข]คือถ้าฉ( ) = F ( + 1 ) = ⋯ = F ( ข )[a,b]f[a,b]f(a)=f(a+1)=⋯=f(b)
โครงสร้างข้อมูลอย่างง่ายของเราจะเป็นแผนผังช่วงเวลา ในคำอื่น ๆ เรามีต้นไม้ไบนารีที่แต่ละโหนดสอดคล้องกับช่วงเวลา (ของดัชนี) เราจะเก็บช่วงเวลาที่สอดคล้องกันในแต่ละโหนดvของต้นไม้ แต่ละใบจะตรงกับช่วงเวลาที่แบนและพวกเขาจะได้รับการจัดเพื่อให้อ่านออกใบซ้ายไปขวาจะช่วยให้เราลำดับของช่วงเวลาแบนติดต่อกันซึ่งเป็นเคล็ดและมีสหภาพแรงงานคือทั้งหมดของ[ 1 , n ] ช่วงเวลาสำหรับโหนดภายในจะเป็นการรวมกันของช่วงเวลาของลูกทั้งสอง นอกจากนี้ในโหนดใบไม้แต่ละโหนดℓเราจะเก็บค่าV ( ℓ )I(v)v[1,n]ℓV(ℓ)ของฟังก์ชันในช่วงเวลาI ( ℓ ) ที่สอดคล้องกับโหนดนี้ (โปรดทราบว่าช่วงนี้แบนดังนั้นfคือค่าคงที่ในช่วงเวลาดังนั้นเราจึงเก็บค่าfเดียวในโหนดใบแต่ละโหนด)fI(ℓ)ff
เท่ากันคุณสามารถจินตนาการได้ว่าเราแบ่งพาร์ติชันออกเป็นช่วงแบน ๆ แล้วโครงสร้างข้อมูลคือแผนภูมิการค้นหาแบบไบนารี่โดยที่ปุ่มเป็นจุดสิ้นสุดด้านซ้ายของช่วงเวลาเหล่านั้น ใบมีค่าfในช่วงดัชนีบางช่วงที่fมีค่าคงที่[1,n]ff
ใช้วิธีการมาตรฐานเพื่อให้แน่ใจว่าต้นไม้ไบนารียังคงสมดุลเช่นความลึกของมันคือ (โดยที่mจะนับจำนวนใบปัจจุบันในต้นไม้) แน่นอนm ≤ nดังนั้นความลึกจึงอยู่ที่O ( lg n )เสมอ สิ่งนี้จะเป็นประโยชน์ด้านล่างO(lgm)mm≤nO(lgn)
ตอนนี้เราสามารถสนับสนุนการดำเนินการรับและตั้งค่าดังนี้:
เป็นเรื่องง่ายที่เราสำรวจต้นไม้ที่จะหาใบที่มีช่วงเวลาที่มีฉัน นี่เป็นเพียงการสำรวจแผนภูมิการค้นหาแบบไบนารี ตั้งแต่ความลึกเป็น O ( LG n ) , เวลาการทำงานเป็น O ( LG n )get(i)iO(lgn)O(lgn)
เป็นเล่ห์เหลี่ยม มันทำงานได้เช่นนี้:set([a,b],y)
ก่อนอื่นเราจะพบช่วงเวลาของใบไม้ที่มีa ; ถ้า0 <แล้วเราแบ่งช่วงเวลานี้ใบเป็นสองช่วง[ 0 , - 1 ]และ[ , ข0 ] (ดังนั้นการเปลี่ยนใบเหลืองนี้เป็นโหนดภายในและแนะนำเด็กสองคน)[a0,b0]aa0<a[a0,a−1][a,b0]
ต่อไปเราจะพบช่วงเวลาของใบไม้ที่มีb ; ถ้าb < b 1เราแบ่งช่วงเวลาของใบไม้นี้เป็นสองช่วง[ a 1 , b ]และ[ b + 1 , b 1 ] (ดังนั้นจึงเปลี่ยนโหนดใบนี้เป็นโหนดภายในและแนะนำลูกสองคน)[a1,b1]bb<b1[a1,b][b+1,b1]
ณ จุดนี้ฉันอ้างว่าช่วงเวลาสามารถแสดงเป็นช่วงเวลาที่แยกจากกันของO ( lg n )ช่วงเวลาที่สอดคล้องกับชุดย่อยบางส่วนของโหนดO ( lg n )ในต้นไม้ ดังนั้นลบลูกหลานทั้งหมดของโหนดเหล่านั้น (เปลี่ยนเป็นใบ) และการตั้งค่าที่เก็บไว้ในต่อมน้ำเหล่านั้นไปยังY[a,b]O(lgn)O(lgn)y
ในที่สุดเนื่องจากเราปรับเปลี่ยนรูปร่างของต้นไม้เราจะทำการหมุนที่จำเป็นเพื่อปรับสมดุลต้นไม้อีกครั้ง (โดยใช้เทคนิคมาตรฐานใด ๆ เพื่อรักษาสมดุลของต้นไม้)
เนื่องจากการดำเนินการนี้เกี่ยวข้องกับการดำเนินงานที่เรียบง่ายไม่กี่โหนด (และชุดของโหนดที่สามารถพบได้ง่ายในO ( LG n )เวลา), เวลาทั้งหมดสำหรับการดำเนินการนี้เป็นO ( LG n )O(lgn)O(lgn)O(lgn)
สิ่งนี้แสดงให้เห็นว่าเราสามารถรองรับทั้งการรับและการตั้งค่าในเวลาต่อการดำเนินการ ในความเป็นจริงเวลาทำงานสามารถแสดงเป็นO ( lg min ( n , s ) )โดยที่sคือจำนวนชุดปฏิบัติการที่ดำเนินการจนถึงปัจจุบันO(lgn)O(lgmin(n,s))s
การเพิ่มการรองรับสำหรับการเพิ่ม
เราสามารถปรับเปลี่ยนโครงสร้างข้อมูลข้างต้นเพื่อให้สามารถรองรับการดำเนินการเพิ่ม โดยเฉพาะอย่างยิ่งแทนที่จะเก็บค่าของฟังก์ชันในใบไม้มันจะถูกแทนด้วยผลรวมของตัวเลขที่เก็บอยู่ในชุดของโหนด
แม่นยำมากขึ้นค่าของฟังก์ชั่นในการป้อนข้อมูลที่ฉันจะได้รับคืนเป็นผลรวมของค่าที่เก็บไว้ในโหนดบนเส้นทางจากรากของต้นไม้ลงไปใบที่มีช่วงเวลาที่มีฉัน ในแต่ละโหนดVเราจะเก็บค่าV ( วี) ; ถ้าv 0 , v 1 , … , v kแสดงถึงบรรพบุรุษของ leaf v k (รวมถึง leaf เอง) จากนั้นค่าของฟังก์ชันที่I ( v k )จะเป็นf(i)iivV(v)v0,v1,…,vkvkI(vk) )V(v0)+⋯+V(vk)
มันง่ายในการสนับสนุนการดำเนินการรับและตั้งค่าโดยใช้ชุดตัวเลือกต่าง ๆ ของเทคนิคที่อธิบายไว้ข้างต้น โดยทั่วไปในขณะที่เราสำรวจต้นไม้ลงเราติดตามผลรวมการทำงานของค่าเพื่อให้สำหรับแต่ละโหนดว่าไปสำรวจเส้นทางที่เราจะรู้ว่าผลรวมของค่าของโหนดบนเส้นทางจากรากที่x เมื่อเราทำเช่นนั้นแล้วการปรับใช้การรับและการตั้งค่าที่อธิบายไว้ข้างต้นอย่างง่ายดายจะเพียงพอxx
และตอนนี้เราสามารถรองรับการอย่างมีประสิทธิภาพ ครั้งแรกที่เราแสดงช่วงเวลา[ , B ]เป็นสหภาพของO ( LG n )ช่วงเวลาที่สอดคล้องกับชุดบางส่วนของO ( LG n )โหนดในต้นไม้ (แยกโหนดที่ปลายทางซ้ายและปลายทางที่เหมาะสมถ้าจำเป็น) เหมือนกับที่ทำในขั้นตอนที่ 1-3 ของการตั้งค่า ตอนนี้เราเพียงแค่เพิ่มδให้กับค่าที่เก็บไว้ในแต่ละO ( lg n )add([a,b],δ)[a,b]O(lgn)O(lgn)δO(lgn)โหนด (เราไม่ลบลูกหลานของพวกเขา)
สิ่งนี้มีวิธีในการสนับสนุนรับตั้งค่าและเพิ่มในเวลาต่อการดำเนินการ ในความเป็นจริงเวลาทำงานต่อการดำเนินการคือO ( lg min ( n , s ) )โดยที่sจะนับจำนวนชุดการดำเนินการบวกจำนวนการเพิ่มการดำเนินการO(lgn)O(lgmin(n,s))s
รองรับการทำงานแบบแทง
แบบสอบถามแบบแทงเป็นสิ่งที่ท้าทายที่สุดสำหรับการสนับสนุน แนวคิดพื้นฐานจะแก้ไขโครงสร้างข้อมูลข้างต้นเพื่อรักษาค่าคงที่เพิ่มเติมต่อไปนี้:
(*) ช่วงเวลาสอดคล้องกับแต่ละ leaf ℓคือช่วงสูงสุดแบบแบนI(ℓ)ℓ
ที่นี่ผมบอกว่าช่วงเวลาเป็นช่วงเวลาแบนสูงสุดถ้า (i) [ , ข]จะแบนและ (ii) ช่วงเวลาไม่มีมี[ , ข]แบน (ในคำอื่น ๆ สำหรับทุก' , b ′พอใจ1 ≤ a ′ ≤ a ≤ b ≤ b ′ ≤ nทั้ง[ a ′ , b ′ ] = [[a,b][a,b][a,b]a′,b′1≤a′≤a≤b≤b′≤nหรือ [ a ′ , b ′ ]ไม่แบน)[a′,b′]=[a,b][a′,b′]
สิ่งนี้ทำให้การดำเนินการแทงง่ายต่อการใช้งาน:
- ค้นหา leaf ที่ช่วงเวลามี iและจากนั้นส่งคืนช่วงเวลานั้นstab(i)i
อย่างไรก็ตามตอนนี้เราจำเป็นต้องแก้ไขการตั้งค่าและเพิ่มการดำเนินการเพื่อรักษาค่าคงที่ (*) ทุกครั้งที่เราแยกใบออกเป็นสองเราอาจละเมิดคงที่ถ้าบางคู่อยู่ติดกันของใบช่วงเวลาที่มีค่าเดียวกันของฟังก์ชันฉโชคดีที่การดำเนินการแต่ละชุด / เพิ่มเพิ่มได้มากที่สุด 4 ช่วงเวลาลีฟใหม่ นอกจากนี้สำหรับแต่ละช่วงเวลาใหม่นั้นจะง่ายต่อการค้นหาช่วงเวลาของใบไม้ทันทีไปทางซ้ายและขวาของมัน ดังนั้นเราสามารถบอกได้ว่าค่าคงที่ถูกละเมิดหรือไม่ ถ้าเป็นเช่นนั้นเราจะรวมช่วงเวลาที่อยู่ติดกันโดยที่fมีค่าเท่ากัน โชคดีที่การรวมช่วงเวลาสองช่วงที่อยู่ติดกันไม่ได้ทำให้เกิดการเปลี่ยนแปลงเรียงซ้อน (ดังนั้นเราจึงไม่จำเป็นต้องตรวจสอบว่าการควบรวมกิจการอาจมีการละเมิดค่าคงที่เพิ่มเติมหรือไม่) ในทั้งหมดนี้เกี่ยวข้องกับการตรวจสอบ12ffคู่ของช่วงเวลาและอาจรวมเข้าด้วยกัน ในที่สุดเนื่องจากการควบรวมกิจการเปลี่ยนแปลงรูปร่างของต้นไม้ถ้าสิ่งนี้เป็นการละเมิดดุลคงที่ให้ทำการหมุนเวียนที่จำเป็นเพื่อรักษาความสมดุลของต้นไม้ (ทำตามเทคนิคมาตรฐานในการรักษาสมดุลต้นไม้ไบนารี) โดยรวมแล้วสิ่งนี้จะเพิ่มงานเพิ่มเติม O ( lg n )ส่วนใหญ่ให้กับการดำเนินการ set / add12=O(1)O(lgn)
ดังนั้นโครงสร้างข้อมูลขั้นสุดท้ายนี้สนับสนุนทั้งสี่การดำเนินงานและเวลาการทำงานสำหรับการดำเนินงานแต่ละคนคือ ) การประมาณการที่แม่นยำยิ่งขึ้นคือเวลาO ( lg min ( n , s ) )ต่อการดำเนินการโดยที่sจะนับจำนวนชุดและเพิ่มการดำเนินการO(lgn)O(lgmin(n,s))s
พรากจากความคิด
ว้านี่เป็นโครงการที่ค่อนข้างซับซ้อน ฉันหวังว่าฉันจะไม่ทำผิดพลาดใด ๆ โปรดตรวจสอบงานของฉันอย่างรอบคอบก่อนที่จะพึ่งพาวิธีนี้
add
จะเป็นเส้นตรงในจำนวนช่วงเวลาย่อยของแม้ว่า; คุณเคยคิดเกี่ยวกับต้นไม้สเปรย์ที่มีโหนด“ ” ที่แตกต่างกันอย่างมาก