Problem
https://vn.spoj.com/problems/GSS
https://oj.vnoi.info/problem/GSS
Cho dãy số a[1], a[2], …, a[n] ( | a[i] | <= 15000, n <= 50000). |
Hàm q(x, y) = max { tổng(a[i]+a[i+1]+…+a[j]), x <= i <= j <= y }.
Cho m câu hỏi dạng x, y (1 <= x <= y <= n). (m <= 50000) -> hãy tính các q(x, y).
- Dòng đầu là n.
- Dòng thứ hai là dãy a.
- Dòng thứ 3 là m.
- m dòng tiếp theo mỗi dòng là 1 cặp số x, y.
Output
Lần lượt ghi ra các q(x, y) tương ứng. Mỗi kết quả ghi trên 1 dòng.
Example
Input
3
-1 2 3
1
1 2
Output
2
Tutorial
Bài này sử dụng segment tree, trong đó mỗi node lưu lại các thông tin:
sum
: tổng giá trị các phần tử trên đoạnprefix
: tiền tố lớn nhất trên đoạnsuffix
: hậu tố lớn nhất trên đoạnbest
: tổng lớn nhất trong đoạn
Khi merge hay combine hai node con vào node cha trên cây segment, ta dễ dàng có được các công thức sau:
sum = l.sum + r.sum;
prefix = max(l.prefix, l.sum + r.prefix);
suffix = max(r.suffix, r.sum + l.suffix);
best = max(l.best, r.best, l.suffix + r.prefix);
// trong đó: l, r là hai node con của node cần merge.
Submission
Nếu bạn thấy bài viết này hay, hãy share bài viết này cho mọi người nhé 😉.
Share this post →