square root decomposition + quicksum
ถ้าสมมติเรา ทำตรงๆ
for (i = L; i <= R: i += step) sum += input[i];
แบบนี้จะใช้เวลา O(question * (n / step))
ถ้า step มีค่า 1,2,3,4,5 ก็จะมีค่าประมาณ O(question * n)
เราเลยต้องคิดว่า
เราก็เลยจะคำนวนตัวน้อยๆไว้ก่อน เช่น คำนวน step=1 ด้วย quicksum ปกติ
step=2
เราก็ต้องแยกเคสว่าตำแหน่งเริ่มต้นเป็นอะไรใน 0, 1
step=3
เราก็ต้องแยกเคสว่าตำแหน่งเริ่มต้นเป็นอะไรใน 0, 1, 2
step=4
เราก็ต้องแยกเคสว่าตำแหน่งเริ่มต้นเป็นอะไรใน 0, 1, 2, 3
step=k
เราก็ต้องแยกเคสว่าตำแหน่งเริ่มต้นเป็นอะไรใน 0, 1, 2, 3, ..., k-2, k-1
quicksum[step, i] = quicksum[step, i - step] + input[i]
แล้วทำถึงค่า k ที่เท่าไหร่ถึงจะดีหละ ?
ก็ตั้งสมการ
k
ใช้ O(n * k)
q
ครั้ง
< k
คำนวนใน O(1)
เพราะมี quicksum ที่คำนวนไว้แล้ว> k
คำนวนใน O(n / k)
เพราะต้องวน forO(q * n / k)
เวลารวม = O(n * k) + O(q * n / k) = O(n * (k + q / k))
ต้องการให้เวลารวมน้อยสุด คือให้ k = sqrt(q)
จะได้ = O(n * (sqrt(q) + sqrt(q)))
เป็นเวลาที่ทำได้ดีสุดใน worse case แล้ว ถ้าเราให้ n = q
ก็จะได้คำตอบเป็น O(n * sqrt(n))