/ 最近 .rdf 追記 編集 設定 本棚

脳log[20250714]



2025年07月14日 (月) [AtCoder] 精進。先週(20250712)あった ABC404-F「Jump Traveling」(黄 diff)。コンテスト終了後に「距離 K の隣接頂点があるなら頂点1から BFS をするだけ。距離 K の頂点集合を得る方法はあるか?」と書いていた。まず、BFS をするだけではないらしい。遷移先が多くなりすぎるのだろうか。kotatsugame さんの動画を見たんです(【競技プログラミング】ABC414【実況】)。いみじくも「頂点1を根としたときの深さだけでなんとかできる?」とも書いていたのだけど、そのための秘密兵器が頂点を BFS 順に並べる、ということらしいです。そうするとある頂点の子や、ある頂点の K 階層下の子孫を区間で表すことができる。かつて PAST1-K「巨大企業」を解くにあたって頂点を DFS 順に並べること、それをオイラーツアーと呼ぶことなどを学んだけれど(20200607p01)、今日初めて BFS 順に並べることの利点を1つ知りました。解法のポイントも聞こえてきました。K=a+b であるとして、a 階層上に上がってから b 階層下る移動を考えるとき、a 上がるときに通って来たパスを引き返すように b 下る移動は不正なので除外しなければいけない。でも、b 階層下の子孫も、同じ階層にある除外すべき子孫も、どちらも区間(包含関係にあります)なので扱いが容易。訪問済みフラグを BIT で管理したら BIT 上の二分探索で区間内の未訪問の頂点を効率良く見つけることができる。■提出 #67602188 (WA×34/AC×19 / 2933 ms)。なんでやねん、サンプル通ったやんけ。サンプルが通るまでにも色々ありました。K 階層下の子孫だけでいいかと思ったら1から K まで必要だし、BFS 順に並べるって言ってんのに DFS をしていたりもしました。それなのにサンプルの1は答えが合うんですよ。役に立たねーな。■提出 #67603447 (AC / 2904 ms)。お風呂デバッグをしてきました。頭や体を洗っているあいだは持ち込んだ雑誌を読むこともできないので、ぼんやり考えるのに最適な時間。変更点は 87 行目の1文字だけ。up<kup<=k にした。頂点1に向かって K 階層遡っても、それって1手前にいた頂点だから無駄じゃね? と思って、移動先を K 階層下、1階層上のち K-1 階層下、2階層上のち K-2 階層下、……、K-1 階層上のち1階層下に限定していたのだけど、まっすぐ K 階層上も移動先に加えるべきだったということ。なぜか。折れ曲がるように移動して到達した頂点からまっすぐ K 階層上というのは、初めて訪れる場合がある。K 階層まっすぐ下るだけが移動じゃないのだから「1手前にいた頂点だから無駄じゃね?」は勘違い。■Crystal で通している人の提出 #67550795 を見ましたが、えー、全然違うー。Ruby で同じことをして通りますか? だったらだいぶ短く簡潔に解けるということだけど。■■■寝て起きたらフレンズさんのツイート()や他のブログで読んだことが頭に入ってきた気がする。たぶんだけど BFS をするのかな。頂点ごとに訪問済みフラグを持つわけだけど、追加で K 状態を区別する。これは K 歩の何歩目で訪れたのかを表す。さらに追加で直前の頂点も持つ。直前の頂点へは次の移動ができないのでこれも状態として区別する必要がある。そうすると状態数が NNK になってよろしくないのだけど、直前の頂点が2種類あるとその後の遷移はすべて網羅できているので、3番目以降の直前の頂点フラグはすでに立っているものとして良い。ということが書いてあって、同じことを(もしくは不正確なこと不十分なことを)繰り返しているだけだと思うんだけど、昨日説明を読んだときは何を言っているのかちんぷんかんぷんだったんだよね。何度文字列をなぞっても頭に入って来なかった。脳みその可塑性応答性が低い!■提出 #67610103 (WA×34/AC×19 / 665 ms)。2NK 状態の BFS を書いてみたけど WA だった。サンプルは通るんだけど何が足りないんだろう。■提出 #67610224 (TLE×2)。バグの原因はちょうど K ステップの移動の次の一歩は直前の頂点がどこかに関係なく移動できるということを考え忘れていたこと。これを直して十分に遷移ができるようになったら WA がなくなって TLE が2つ出た。3.3 秒 以下の 3098 ms と 3225 ms だからあとちょっとなんだよなあ。■提出 #67610541 (AC / 2809 ms)。変なことしないで3要素の配列をキューに入れたら良かった。自分で書いたから Crystal の人のスクリプトも読めるようになったけど、N+N の状態数で K ステップを1単位とする BFS をやっているだけに見える。本当に? それだと K ステップの中間ステップが重複する無駄が生じない? (K 歩ごとに直前の頂点フラグがリセットされているようだから)