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, 1step=3 เราก็ต้องแยกเคสว่าตำแหน่งเริ่มต้นเป็นอะไรใน 0, 1, 2step=4 เราก็ต้องแยกเคสว่าตำแหน่งเริ่มต้นเป็นอะไรใน 0, 1, 2, 3step=k เราก็ต้องแยกเคสว่าตำแหน่งเริ่มต้นเป็นอะไรใน 0, 1, 2, 3, ..., k-2, k-1quicksum[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))