ABC472 C - On a Diet

ダイエット

考え方

まず、愚直に考える。
毎日、直前 $M-1$ 日の摂取カロリー合計を求め、それに今日の分を足して $K$ を超えるか判定する。
超えるなら食べない、超えないなら食べる、という処理をすればよい。
これで、$O(NM)$ でなら解けるが、大きい入力だと TLE してしまう。

そこで、sliding window法で高速化する。
最初のうちは、毎日の判定後に今日の摂取カロリーを加えれば、次の日の判定基準となる。
$M+1$ 日目から先は、それに加えて判定前にちょうど $M$ 日前の摂取カロリーを引く。
こうすると判定基準の「直前 $M-1$ 日の摂取カロリー合計」が足し算と引き算 $1$ 回ずつで求まり、高速。
全体で計算量は $O(N)$ となる。

食べなかったという情報の持ち方は様々ある。
食べなかった時には A を $0$ に書き換えて $0$ カロリー食べたことにしてしまうのが、分岐が減って楽。

入力例1での動作

入力を受け取る。

n: 5
m: 3
k: 83
a: {48, 73, 59, 90, 21}

判定前には、直前 $M-1$ 日で実際に食べたおやつのカロリー合計を持っておく。

日 判定前の合計 今日を食べると 判定 判定後の合計
$1$ $0$ $0+48=48$ $83$ 以下なので食べる $48$
$2$ $48$ $48+73=121$ $83$ を超えるので食べず、$A_2=0$ にする $48$
$3$ $48$ $48+59=107$ $83$ を超えるので食べず、$A_3=0$ にする $48$
$4$ $48-48=0$ $0+90=90$ $83$ を超えるので食べず、$A_4=0$ にする $0$
$5$ $0-0=0$ $0+21=21$ $83$ 以下なので食べる $21$

処理後の $A$ は $(48,0,0,0,21)$ となる。
正の値なら Yes、$0$ なら No なので、各日の答えは順に Yes, No, No, No, Yes となる。

注意点

$K$ と、直前の日々で食べたおやつのカロリー合計は、int 型からはみ出る場合がある。
long long 型を用いること。

別解

特になし。