สมมติว่าคุณมีอาร์เรย์ที่ว่างเปล่า:
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 ไบนารีได้อย่างไร
เคล็ดลับคือการใช้ทรีดัชนีแบบไบนารีสองต้นคือ BIT1 และ BIT2 ซึ่งผลรวมสะสมจะถูกคำนวณจากเนื้อหา ในตัวอย่างนี้นี่คือสิ่งที่เราต้องการเก็บไว้ในต้นไม้สองต้น:
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 ช่วง:
เราต้องทำการอัปเดตช่วงจาก +5 เป็นดัชนี 3..7 สำหรับ BIT1
เราต้องทำการอัปเดตช่วงจาก +10 เป็นดัชนี 3..7 สำหรับ BIT2
เราต้องทำการอัปเดตช่วง -25 ถึงดัชนี 8..9 สำหรับ BIT2
ทีนี้ลองทำการแปลงอีกครั้ง แทนที่จะเก็บค่าที่แสดงด้านบนสำหรับ BIT1 และ BIT2 เราจะเก็บผลรวมสะสมจริง ๆ สิ่งนี้ช่วยให้เราทำการอัปเดต 3 ช่วงด้านบนได้โดยทำการอัปเดตผลรวมสะสม 4 รายการ:
BIT1sum[3] += 5
BIT1sum[8] -= 5
BIT2sum[3] += 10
BIT2sum[8] -= 35
โดยทั่วไปอัลกอริทึมในการเพิ่มค่า v ลงในช่วง [i..j] จะเป็น:
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])
ต้นไม้เฟนวิคเก็บผลรวมไว้ในต้นไม้ไบนารี มันเป็นเรื่องง่ายที่จะทำการอัปเดตที่แสดงด้านบนของต้นไม้ FenwickO ( บันทึกn ) เวลา.
sum[i] = BIT1[i] * i - BIT2[i]
? ดูเหมือนว่าจะใช้งานได้ แต่ดูเหมือนว่าจะเป็นข้อ จำกัด ... อะไรที่ทำให้คุณเข้าใจได้