Editorial for Bedao Testing Contest 01 - KTHSUM


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Author: mbfibat

Subtask 1: ~N \le 1000~

Ở subtask này, do ~N~ khá nhỏ, nên ta có thể sinh ra toàn bộ tổng của các đoạn con liên tiếp, cho vào một mảng, sắp xếp mảng đó lại, và lấy ra kết quả tương ứng.

Subtask 2: ~N \le 10^5~

Để giải bài toán này, một hướng tiếp cận mà ta có thể nghĩ tới đó là kĩ thuật tìm kiếm nhị phân. Cụ thể, định nghĩa hàm ~f(x)~ là số lượng đoạn con liên tiếp trong mảng ~A~ có tổng lớn hơn hoặc bằng ~x~. Khi đó, dễ dàng nhận thấy f(x) là một mảng giảm đơn điệu, khi x tăng thì f(x) giảm. Do đó, ta có thể sử dụng kĩ thuật tìm kiếm nhị phân, để tìm giá trị ~x~ lớn nhất, sao cho ~f(x) \ge k~. Khi đó, x chính là kết quả cần tìm của ta.

Vậy nên giờ ta có thể chuyển về bài toán sau: Cho mảng ~A~ và một số nguyên ~x~, đếm xem có bao nhiêu đoạn con liên tiếp có tổng lớn hơn hoặc bằng ~x~. Với những bài liên quan tới tổng của một đoạn con liên tiếp, chúng ta có thể nghĩ tới kĩ thuật tổng tiền tố. Gọi ~pSum(i)~ là tổng tiền tố từ phần tử ~1~ đến ~i~, khi đó, ta cần đếm số lượng đoạn (L, R] trong mảng ban đầu, sao cho:

~pSum(R) - psum(L) \ge x~

~\Leftrightarrow psum(R) - x \ge psum(L)~

Đến đây, chúng ta có thể sử dụng các cấu trúc dữ liệu khác nhau như Fenwick Tree, Segment Tree, ... để giải bài toán trên.


Comments

Please read the guidelines before commenting.


There are no comments at the moment.