そのうち誰かの役に立つ

もしくは誰の役にも立たない

AtCoderチャレンジ供養会場(2020/08/01-2020/08/31)

コンテストでの時間切れや解けなかった過去問を振り返って供養していく

8/2: AtCoder beginner Contest 174 F - Range Set Query

供養

問題

Difficulty: 1575 (記事作成時点)

解法

  •  i = 1, \dots, N の順に見ていき、各色  c について最後に登場した位置  \mathit{LA}_{c} を記録しておく
  • BITを用いて  \mathit{LA}_{c} が更新されるたびに
  • クエリを先読みして  R の昇順でソートしておき、 i \ge R_{j} となったときに  \lbrack L_{j}, R_{j} \rbrack区間和を求める

実装は

  1. 長さ  N + 1 の配列  \mathit{LA} を用意する
  2.  N 区間区間和が求められるBIT  B を用意する
    •  \mathit{Query}(l, r) \lbrack l, r \rbrack区間和を求められるとする
  3.  (L_{j}, R_{j}, j) R_{j} について昇順にソートする
    • ソート後の値を  (L_{j}, R_{j}, q_{j}) とする
  4. 長さ  Q の配列  A を用意し、 j = 0 とする
  5.  i := 0, \dots, N - 1 について、以下の操作を実施する
    •  B_{i + 1} = 1 とする
    •  \mathit{LA}_{c_{i}} \gt 0 ならば  B_{\mathit{LA}_{c_{i}}} をデクリメントする
    •  \mathit{LA}_{c_{i}} = i + 1 とする
    •  R_{j} \le i である間、以下の操作を実施する
      •  A_{q_{j}} = \mathit{Query}(L_{j}, R_{j}) とする
      •  j = j + 1 とする
  6.  0 \le j \lt Q について、 A_{j} を出力していく

計算量は  O(N\mathrm{log}N + Q\mathrm{log}N + Q\mathrm{log}Q)

公式解説

躓いた点

  • SetのSegmentTreeで計算してTLE

8/16: AtCoder Beginner Contest 175 D Moving Piece

供養

問題

Difficulty: 1456 (記事作成時点)

解法

  •  i \to P_{i} を辺とすると1つ以上のサイクルからなるグラフができる
  • 各点  i について、 i を始点にグラフ上を周回したときに得られるスコアの最大値を求める
  •  i が属するサイクルの長さを  L_{i} とすると、最大でも  \mathrm{min}(L_{i}, K) ステップまで考えればよい
    • サイクルを1周して得られるスコアが正ならば、サイクルを可能な限り周回した後のスコアで考える

実装は

  1.  P_{i} が0-indexになるよう各要素から  1 を引く
  2.  N 要素の配列  R を用意する
  3.  N \times 2 の配列  L を用意する
  4.  i = 0, \dots, N - 1 について以下の操作を実施する
    •  R_{i} \ne 0 ならば何もせず次に行く
    •  R_{i} = i, p = P_{i}, s = C_{p}, l = 1 とする
    •  p = i となるまで以下の操作を実施する
      •  p = P_{p} とする
      •  s = s + C_{p} とする
      •  l = l + 1 とする
    •  L_{i} = (l, s) とする
  5.  N 要素の配列  A を用意する
  6.  0 \le i \lt N について以下の操作を実施する
    •  (L, S) = L_{R_{i}} とする
    •  A_{i} = C_{P_{i}}, p = i, c = 0, k = \lfloor \frac{K}{L} \rfloor とする
    •  k \gt 0 ならば  A_{i} = \mathrm{max}(k \times S, A_{i}) とする
    •  j = 1, \dots, \mathrm{min}(L - 1, K) について、以下の操作を実施する
      •  p = P_{p} とする
      •  c = c + C_{p} とする
      •  A_{i} = \mathrm{max}(c, A_{i}) とする
      •  j \le K \% L ならば  A_{i} = \mathrm{max}(c + k \times S, A_{i}) とする
      •  j \gt K \% L かつ  k \gt 0 ならば  A_{i} = \mathrm{max}(c + (k - 1) \times S, A_{i}) とする
  7.  \mathrm{max}(A) を出力する

計算量は  O(N^{2})

公式解説

躓いた点

  • 境界値の整理が間に合わず時間切れ

8/22: AtCoder Beginner Contest 176 E - Bomber

供養

問題

Difficulty: 1187 (記事作成時点)

解法

  •  x 座標と  y 座標を独立に爆破できる建物の数を数えておく
  • それぞれの方向で最大に爆破できる座標の集合を  X, Y、爆破できる建物の数をそれぞれ  R, C とする
  •  (x \in X, y \in Y) を見ていき、1つでも爆破対象が存在しない座標があれば最大値は  R + C、そうでなければ  R + C - 1 となる

実装は

  1.  H 個の配列  X W 個の配列  Y を用意する
  2.  0 \le i \lt M について、爆弾の座標  (h_{i}, w_{i}) について  X_{h_{i}} Y_{w_{i}} をそれぞれインクリメントする
    • 座標は0-indexに変換しておく
  3.  R = \mathrm{max}(X), C = \mathrm{max}(Y) とする
  4. 配列  X^{'}, Y^{'} を用意する
  5.  0 \le i \lt H について  X_{i} = R ならば  i X^{'} に追加する
  6.  0 \le i \lt W について  Y_{i} = C ならば  i Y^{'} に追加する
  7.  x \in X^{'} について以下の操作を実施する
    •  y \in Y^{'} について以下の操作を実施する
      •  (x, y) に爆破対象が存在しなければ  R + C を出力して終了
  8.  R + C - 1 を出力する

計算量は  O(H + W + M)

公式解説

躓いた点

  • 最大値の組合せを都度探索しようとして時間切れ