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

脳log[20260207]



2026年02月07日 (土) [AtCoder] 今日は AtCoder Beginner Contest 444 があった。結果はまあぼちぼち。がんばって解いた E 問題が 2000 人くらいにもう解かれていたり。■A 問題 Repdigit。uniq.size でやろうとして String#squeeze メソッドの存在を思い出した。あんまり使い道がわからないメソッド。もう完成しているのに chomp を省いてマジックナンバーを1から2に書き換えたりしていた。■B 問題 Digit Sum。Ruby には digits.sum メソッドがあります。■C 問題 AtCoder Riko。問題文が難しい。あっとこーだーりこ? じゃがりことは似ても似つかなくてまったくわからない。謎の Riko に意識を持って行かれて問題が頭に入ってこない。さすがの 350 点だなとしばし考え込んでいた。全ペアを考えるには N が大きすぎる。ソートしてみようか。最大のものがまず L の候補。それより小さいものが L を作ろうとすると、半分に折り返して大きい方からと小さい方からでペアを作るしか方法がない。そうしてみると、最大のものが L ではない場合は、L の候補は最大と最小の和しかないということもわかってくる。答えの候補は2つしかない。ここで N=1 のケースがありうるか制約を確かめた。ある。最大と最小の和を求めるときに同じ1つの要素を参照するとおかしなことになりそうなので、場合分けをした。あと、答えの順序が昇順に指定されていた。提出直前に、ふと、どうでもいいよねと確認したら昇順と書いてあった。事前に要素数を出力させるのがありがちな罠。最大で2要素なのにソートした。■D 問題 Many Repunit Sum。変化量をメモしておいて、変化量の累積和を計算しながら各桁の値を求め、繰り上がり処理をしていく。しばし手が止まったのは、何桁まで処理すれば十分なのかを考えてのこと。N と A がすべて最大の 200000 のとき、繰り上がりの累積が全体で何桁桁数を増やすのか、考えてみてもわからなくて、事前に用意する配列の大きさが全く見積もれなかった。それで、普段は嫌ってやらないことだけど、配列の自動拡張に甘えてとりあえずやってみる方針で実装をした。出力できるサイズに収まることは確かなので TLE にはならないと思ったけど、提出後もまったく安心はできなかった。■E 問題 Sparse Range。問題を読む。空ではない全区間から選んで数える。一瞬勘違いしかけたけど、要素が1つしかない部分列が「どの 2 つの要素も差が D 以上である」という条件を満たすか否か。満たすんですね。あぶなかった。Array#all? メソッドと Array#any? メソッドでは初期値が異なっていて空配列に対して呼び出したときの結果が違うんですよという(論理的に正しい)ことを私は知っています。問題が理解できたところで、全連続部分列の累積和を列挙する的な処理がしたい。要素を左から見ていって、それまでの始点の累積に対して現在の要素が終点になる場合を考え、また、現在の要素を始点として累積に追加する。単一要素の部分列も対象だから、順番としては現在の要素を始点として追加してから現在の要素が終点となる場合を数える。何を記録しますか? 各要素ごとに有効な区間の右端が決まっている。右端をキーとしてそこまでの範囲を有効な区間とする始点の数を記録した。ところで、有効な区間の右端は区間に含まれるすべての要素によって制約される最小の値になります。現在の要素に照らして、期限を越えた区間を取り除き、長すぎる区間を切り詰めるように累積情報をメンテナンスすると、現在の要素を終点としうる区間の数が数えられる。これを BIT で数えたい。数えたいんだけど、現在の要素が有効な区間をどれだけ右まで伸ばせるかということがすぐにはわからなくて、BIT に区間を計上したり区間を切り詰めたりするための情報が足りなかった。結局それも BIT で予め求めることになった。BIT を使った2段構えでとてもたいへん。たぶんだけど問題を無駄に複雑にしていると思うんだよね。もっとすっきり解けたんじゃないかという気がする。使える頭がないので実装をがんばりました。■30 分残しても F 問題はさっぱり。順位表を見ると F と G を両方解いている人がとても少なく、F を飛ばして G を解いている人がそれなりにいる。今日の F は鬼門ですか? (難しいケースと面倒くさいケースが考えられます。その後わかったことは、G 問題と AI の親和性が高いケースも考えられます)■自分のすべての提出コンテスト成績証。4桁順位で水パフォ +21 レート。ぼちぼちなんだよなあ。■■■E 問題。尺取りというワードをよく見る。各始点ごとにどれだけ範囲を右に伸ばしていけるかということを、範囲内の値を SortedSet で管理しながら調べるらしい。値の範囲が大きすぎるので BIT でこれをやるには座圧が必要。偶然だけど自分の解法では可能な範囲を値ベースではなく添字ベースで管理していたので座圧なしで BIT に情報をのせることができていた。書いていたように別の解法はたしかにあったけど、そちらにはそちらの面倒が(SortedSet がない Ruby には)あったらしく、すっきりした解法はなかったのだった。