Ta sẽ sử dụng kĩ thuật chia để trị để giải quyết bài toán này trong O(n×log(n))
Xét trên đoạn [l,r], ta chia đoạn này thành 2 nửa, [l,mid] và [mid+1,r], với mid là điểm nằm giữa l và r.
Cố định i bằng cách duyệt i trên đoạn [l,mid], khi này, ta có thể chia thành 4 trường hợp:
- x,y∈[i,mid]
- x,y∈[mid+1,r]
- x∈[i,mid], còn y∈[mid+1,r]
- y∈[i,mid], còn x∈[mid+1,r]
Với:
x=min(ai,ai+1,ai+2,...,amid)y=max(ai,ai+1,ai+2,...,amid)
Gọi j là vị trí đầu tiên thuộc [mid+1,r] mà aj<x. Tương tự, gọi k là vị trí đầu tiên thuộc [mid+1,r] mà ak>y. Ta có thể tìm vị trí này bằng cách dùng hai con trỏ
Như vậy, với mọi vị trí thuộc khoảng [i,min(j,k)−1] đều sẽ rơi vào trường hợp 1, đáp án ở đây là (min(j,k)−mid−1)×x×y
Tương tự, với mọi vị trí thuộc khoảng [max(j,k)+1,r] đều sẽ rơi vào trường hợp 2, đáp án là tổng min(amid,amid+1,...,ap)×max(amid,amid+1,...,ap) với p∈[max(j,k)+1,r] ta có thể tính nhanh tổng ở đây bằng mảng tiền tố.
Còn lại trường hợp 3, và 4. Khi này:
- Nếu j<k, ta sẽ lấy x và tổng của min(amid+1,amid+2,...,ap), với p∈(j,k], ta có thể tính nhanh tổng này bằng mảng tiền tố
- Ngược lại, nếu j>k, ta cũng có thể làm tương tự, nhưng với y và tổng của max trên đoạn.
**Code tham khảo:**
cpp#∈cludebits/stdc++.husingnamespacestd;#if