公式
D - 特訓 解説
by
D - 特訓 解説
by
sounansya
\(A_i\) を全て \(A_i - K\) に置き換えることで、 \(K=0\) の場合に帰着させることができます。以降は \(K=0\) の場合を考えます。
特訓期間を \(L\) 日目から \(R\) 日目までとすると、条件は数式で表すと \(\displaystyle \frac1{R-L+1}\sum_{i=L}^R A_i \le 0\) となります。
\(R-L+1 > 0\) より、条件は \(\displaystyle \sum_{i=L}^R A_i \le 0\) と同値であることも分かります。
ここで、 \(A\) の累積和を \(B\) 、つまり \(\displaystyle B_i=\sum_{j=1}^i A_j\) とすると、条件は \(B_R - B_{L-1} \le 0\) となります。つまり、問題は \(B_R \le B_{L-1}\) を満たす整数の組 \((L,R)\) \((L \le R)\) 全てにおける \(R-L+1\) の最大値となります。これは LIS を求める場合と同じように、 \(L\) の候補を単調減少列として持ちながら \(R\) に対して二分探索していくことで求めることができます。
以上を適切に実装することでこの問題に正答することができます。計算量は \(O(N \log N)\) です。
n, k = map(int, input().split())
a = [0] + list(map(int, input().split()))
for i in range(n):
a[i + 1] += a[i] - k
for i in range(n + 1):
a[i] *= -1
q = [(10**18, -1)]
ans = 0
for i in range(n + 1):
if q[-1][0] > a[i]:
q.append((a[i], i))
ng, ok = 0, len(q)
while ok - ng != 1:
vs = (ok + ng) >> 1
if q[vs][0] <= a[i]:
ok = vs
else:
ng = vs
ans = max(ans, i - q[ok][1])
print(ans)
投稿日時:
最終更新: