給定長度為 n 的環形數組,求以多少個位置為起點,使得從該位置開始的前綴和均非負(即沿環走一圈,任意前綴和 ≥ 0)。
a[1..2n],a[i+n] = a[i]。sum[0]=0; sum[i]=sum[i-1]+a[i]。[i-n+1, i] 內的 sum[j] - sum[i-n] ≥ 0 ⇔ 窗口內 sum 最小值 ≥ sum[i-n]。sum 的索引,隊首始終為當前窗口最小值。滑動窗口大小固定為 n。int front = 0, rear = 0, ans = 0;
for (int i = 1; i <= 2*n; ++i) {
// 維護單調性:從隊尾刪除 >= sum[i] 的元素
while (front < rear && sum[i] < sum[id[rear-1]]) --rear;
id[rear++] = i;
// 窗口形成(i >= n)時檢查條件
if (i >= n) {
if (sum[id[front]] >= sum[i-n]) ++ans;
// 移除滑出窗口的元素
if (id[front] == i-n+1) ++front;
}
}
sum[0] 參與比較。HDU 4193 是單調隊列求滑動窗口最小值的經典應用。將環形問題展開為線性、轉化為前綴和差值條件、再用單調隊列維護窗口最小值,是解決此類問題的標準套路。