/ 最近 .rdf 追記 設定 本棚

脳log[2022-08-16~]



2022年08月16日 (火) [AtCoder] 復習。ABC258-E「Packing Potatoes」。20220720 に書いたようにこの手の問題は計4問解いてるけど、どれも ρ 型になる遷移グラフを明らかにする、めんどうくさくて間違えやすい方法で解いていた。今では LCA のためにダブリングを実装した経験もあることだし(20210617p01)、この手の問題でもダブリングを使ってみたいな、と。■提出 #34096860 (AC / 389 Byte / 1585 ms)。485 ms と比べるとかなり遅くなる。


2022年08月15日 (月) [AtCoder] 精進。AGC058-A「Make it Zigzag」(緑 diff)。■最初は長さ 2N のソート済み数列を前半後半に分けて交互にファスナー状に配置したらジグザグになるじゃないかと考えた。たとえば N=3 のとき、作る数列を 1,4,2,5,3,6 と決め打つということ。交換回数は転倒数でわかる。提出前に気がついたんだけど、解答に「以下の操作を 0 回以上 N 回以下行うことができます」という制約が付いていた。一応ね、実装前にざっと制約を探しはしていた。でも制約セクションには入力の制約は書いてあっても出力の制約は書かれていなかったのだな。転倒数の総和の最大値はたぶん入力となる数列が逆順にソートされている場合で、0 から 2N-1 の範囲の和(=N(2N-1))になるから、入力次第で操作回数が N を超える。■次に考えたのは、入力の先頭を出力の先頭にとりあえず配置して、次に配置する要素を、出力の末尾との比較によって入力の前の方から貪欲に引っぱってくる方法。考えなければいけないのは、出力の末尾より大きい(小さい)要素が入力の中に残っていないときにどうやってジグザグを維持するか。たとえば出力の末尾2要素が O1,O2 で入力の残りが I1,I2,I3 のときに大小関係が O1<O2<I1<I2<I3 だったら、O2 より小さい要素を入力から選んでジグザグを作ることができない。解決するのは簡単で、入力の先頭を出力の末尾の1つ手前に挿入すればジグザグになる。O1 との大小関係も大丈夫。I1 が O1 より小さいせいでジグザグが壊れるならそもそも苦労していない。この解法のネックも操作回数で、2N の入力のそれぞれに対して 0 回から複数回の操作が必要になる。ランダム入力では N=100000 に対して 180000 回くらいの操作が必要になった。■次に思いついたのは(考えたって書くのやめちゃった)、さっきの解法の例で出した O1,O2,I1,I2,I3 の中で、O2,I1,I2 の大小関係にだけ注目してジグザグが作れるんじゃないかということ。3つの大小関係がどうであれ0回か1回のスワップで山ないしは谷が作れる。(O2 がスワップ対象だけど)スワップによる既成出力への影響はどうか。スワップが必要なのは真ん中の要素が山なら極大値、谷なら極小値になっていなければいけないのにそうではなかったときだから、山を作るためにスワップされたどちらかの端の要素はそれまでより小さくなり、逆に谷を作るためのスワップでは端の要素が大きくなる。山になる要素の隣は谷になるべき要素だから、スワップで小さくなってもジグザグは維持される。谷を作る場合も同じ。■提出 #34071956 (AC / 331 Byte / 212 ms)。N 回のループの各回で1回以下のスワップだから交換回数も大丈夫。精進だからこそトントントンと AC までステップが踏めたんだろうなあ。2番目のトンがなければ AC につながる3歩目のトンはなかったし、次の一歩が出てこないことも2歩目があさっての方向に向いていることもよくあることなので、5割以上の確率で0完になる AGC はリスキーすぎる。緑だったときにレート変動対象から外れて以来不参加だよ。■■■B 問題「Adjacent Chmax」は小さい P から順番に DP かなと思ったけど、何を記録するのかが(実装を始めても)はっきりせず。


2022年08月11日 (木) Blasphemous を A エンドと B エンドでクリアした。3日で 20 時間くらい。エンジェル1人と遺骨1つだけ取り逃していて見つからず。C エンドの条件も満たしたんだけど、クリサンタを倒したあとだったために見られず。クリサンタさん声がとってもステキ。あとこのゲームは世界観がすごく良い。キリスト教的な罪と罰と拷問みたいなエグさ。死こそ福音なりか。■「【Blasphemous/ブラスフェマス】2D版ダークソウル降誕!美麗ドット絵で紡ぐダークファンタジーメトロイドヴァニア【真エンディングへの道】」「【ゆっくり実況】ブラスフェマス Cエンディング RTA 1:41:39 part1/5 - YouTube」 ブックマークしてるチャンネルでプレイしていたので知って買った。


2022年08月10日 (水) 今日読んでた本のタイポ(というより思い違い)。タイポグリセミアという混成語の組成として「低血糖症(ハイパーグリセミア hyperglycemia)」と書かれていた。低なのに hyper? hypo では? と疑問に思って検索したらやっぱり Wikipedia には hypoglycemia と書いてある。そうだと思った。■ここからが自分の鈍いところだけど、タイポグリセミアに残っているのはグリセミアであって低~要素が残ってないし、高血糖症からできあがっていていけない理由はないよねって思ったけど(食い違っている症状名カタカナ英語のどれが間違いで訂正すべき対象なのかを考えていた)、ややあって typo と hypo がかかっていることに気がついたのだった。hypoglycemia だから typoglycemia なのであって低血糖症でなければいけないのだった。


2022年08月09日 (火) [AtCoder] 精進1。先日(20220807)から続く期待値シリーズの第3段。第1回PAST-O「持久戦」。最大の目が出たあとはもう1回だけ振って終了が確定だよね、というところからさかのぼって最初に振るダイスの期待値を求める。■提出 #33926259 (AC / 639 Byte / 1007 ms)。なんのバグもなく。■提出 #33926512 (AC / 272 Byte / 327 ms)。他の提出に比べてやけに遅かったので整理して無駄を省いた。まだ 200 ms 台には届かない。A の値が全部異なるって制約を利用し損ねてるなあ。■■■精進2。同じ第1回 PAST から N 問題「整地」■提出 #33927311 (AC / 375 Byte / 342 ms)。尺取りです。境界に注意してバグらせないように、端っこ(0,W)を処理から漏らさないように。これで第2回(20220724)に続いて第1回もコンプリート。自分のすべての提出


2022年08月07日 (日) [AtCoder] 精進1。第5回PAST-K「的あて」。期待値がさっぱりすぎて公式解説の行間を埋めることさえできず、こちらのユーザー解説のお世話になりました。■提出 #33868500 (AC)。この問題に取り組んだのは今回が初めてではなく、今日の提出の9割はすでに書いてあった。的を一直線に並べて添字を1次元に変換したところでバグらせてそのままだった。1行目の右端と2行目の左端が隣り合っているかのような処理をしていたのがバグの原因。馬鹿が横着するから……。■■■精進2。本命はこちら先週あった LINE Verda プログラミングコンテスト(AtCoder Beginner Contest 263)-E「Sugoroku 3」(ぎりぎり青 diff)。期待値がわからんすぎて「E問題は自己ループのある期待値の問題なのだ! EDPC Jと同じようにして自己ループを無視すれば、累積和を使って解けるのだ!」とヒントをもらってもさっぱりだったので先に「的あて」を解説付きで解いたのだった。■提出 #33870546 (AC / 362 Byte / 206 ms)。答えを出す流れは「的当て」と同じ。最初は有理数(Rational)で答えを出したけど、遅すぎるかもしれず、Ruby でなければそんな便利クラスはないかもしれず、分子と分母を分けて書き直して提出した。■累積和の通分をどうするんだ、と思って最初に Rational を使ったんだけど、Ruby でこの問題1番目の提出である #33836504 にそれっぽい処理は見当たらない。9行目で普通に引き算してる。分母のモジュラ逆数を掛けた結果は小数で割り算した結果と同じような扱いをして構わないってこと?(もちろん法が共通する限りにおいて)■提出 #33871015 (AC / 265 ms)。うん、そうみたい。逆元の計算が余りをとる計算より高コストだから若干遅くなるけど、通分は必要なかった。mod の世界がわかっていないということがわかってしまったね。■この問題は以前「解答の提出フォーマットがすでに謎なんだけども」と書いていたのと同じ提出フォーマットなんだけど、これってたぶん(たぶん!)割り算があるときの mod をどう計算するかという定義が書いてあるのだと思うんだよね。だから「Q/R を mod P で答える」という理解でいいと思う。読んでもそうとは理解できないけど、それ以外にないでしょ、というのはわかる。そして計算方法はこのときから知ってる>「階乗が法外な大きさになるので余りを答える問題。割り算を含む式の余りが求められなかった」。


2022年08月04日 (木) [AtCoder] 精進1。先週あった ARC145-A「AB Palindrome」(茶 diff)。まず、A.*B 型の入力はどうやっても不可。次に、文字数が奇数のときは中心に自由に使える文字があるので、左右どちらの半分の文字列に対しても右から寄せるような操作も左から寄せるような操作も好きに選ぶことができるので、左右ともに好きな文字列に書き換えられて回文にもできる。ここまでは当日にもわかっていた。今日お風呂で考えていて気がついたのは、ある程度の文字数があればどんな入力でも BA+B+A+B 型か AB+A+B+A 型の文字列に書き換えられるな、ということ。要するに最低5文字あって A.*B 型でなければ常に Yes。というわけであとは N=2 と N=4 だけケアできれば良い。■提出 #33772876 (AC / 258 Byte / 86 ms)。ほとんどどんな文字列でも回文に書き換えられるので、入力の長さと4文字だけ見れば答えが出せる。なんだよそれー。縛りがざる過ぎて逆に手掛かりが少ないのが難しい。■@2022-08-10 それどころではなかったな。こちらの提出 #33643866 (AC / 75 Byte) を見ると A.*B 型と N=2 だけケアすれば答えが出せたらしい。■■■精進2。同 ARC-B「AB Game」(茶 diff)。公倍数を使うのかなとか予想しながら考えてみたらもっと単純だった。まず N/A、N/B でそれぞれが可能な操作回数の最大がわかる。この時点で N/A = 0 なら Alice の負けが確定する。それぞれ最大の回数が決まっていて、自分の操作回数を残しながら相手の操作回数を削るには……とか考え始めたんだけど、もし A<=B なら Alice が最大限取り去った残りは B より少ないのが決まっていて Bob は1回も操作できない。これは逆も言えて、もし A>=B で Bob に操作が回ったなら Alice に勝ちの目はない。0手1手2手までで全部決まる。■提出 #33773060 (AC / 149 Byte / 59 ms)。A の剰余(0..A-1)が A..N のあいだに何周といくつあるかを N/A と N%A で数えるだけ。~だけって言うなら当日に AC を取りなさいよ。


2022年07月31日 (日) [AtCoder] 今日は ABC262 があった。最近頭の中に蜘蛛の巣が張っていて ARC でも ABC でもいいことがない。時間内には解けなかったけど手応えがあった F 問題「Erase and Rotate」について書いて気持ちを良くする。■操作を繰り返して辞書順最小の数列を作る。制約から数列は空にはならない。■1.まずどの要素を先頭にするか決める。これは操作回数の制約の中で先頭に持って来られる要素のうち最小のもの。■2.次は2通り考える。先頭の要素をどのようにして先頭に持ってきたか。前にある要素を削除したか、ローテートして後ろのものを前に持ってきたか。■2-A.簡単なのは前にある要素を削除して先頭を先頭に持ってきた場合。残りの操作回数で隣接2項が減少している場所を見つけて一方を取り除く。前の方から数列が昇順になるように整形するということ。それでも操作回数が余ったら末尾の要素を取り除いて数列を短くする。並びが同じなら短い方が良い。他の人の提出を見ていたら、ステップ1を飛ばしてこの操作をしても自動的に先頭になるべき要素が先頭に出てきて同じ結果になるらしい。■2-B.ローテートして先頭を先頭に持ってきた場合は数列を2つに分ける。ローテートした部分と、それ以外の部分。それ以外の部分は2-Aと同じ処理をして答えの数列の後半部分とする。先頭を先頭に持ってくるためにローテートした部分というのは、実はローテートする代わりに削除したとしても構わない。どちらが得か。答えの数列の後半の先頭の要素より小さくて昇順になっている限りにおいて削除せずに保存する。■TLETLEAC。■難しくてわからんという問題ではなくて、実装が大変、見落としが怖いという問題だったと思う。門前払いにせず手を動かしただけ達成感を与えてくれる問題で好き。黄 diff なのは6問目で時間がなかったか細部を詰め切れなかったかだと思う。


2022年07月28日 (木) [AtCoder] 精進。第5回PAST-N「旅行会社」。見覚えがない問題。いつ頃までかは PAST の L 問題以降に諦めムードが漂っていたっけね。一直線に都市が並んでおり、隣接する都市が条件付きの道で繋がっている。異なる条件を持つ複数の人が異なる都市から出発するとき、それぞれの人の移動可能範囲は?■提出 #33559884 (AC / 4000 ms)。左端から右端へ、また、右端から左端へ、都市を移動しながら出発地点にいる人を拾い、条件から外れた人を捨てていく。時間制限が厳しい。座圧 BIT で頑張る。■@2022-08-10 違う方針でもっと速い提出 #33771637 (qib さん / 2388 ms)。だけどこれがほとんど同じ内容で配列をソートしていただけで TLE になるんだから配列の比較は遅い>提出 #33771584 (TLE / 4242 ms)。44xx ms ではないから 242 ms だけオーバーしてる。


2022年07月27日 (水) [AtCoder] @chokudai「回答3つ目はおしゃれ解法。この考え方を持つとなんでもできるようになる https://t.co/EybFejQMHi」■先週「ABC132-E「Hopscotch Addict」(ギリギリ青 diff)。気がつけばなんてことのない問題。BFS をケン、ケン、パで3倍頑張るだけ」と書いていた人間がこのツイートを「あっ、そうか。へー」と読んでいてはいけないと思うんだよね。脳みそがお留守なんだよな。


2022年07月26日 (火) [AtCoder] 精進。ABC212-E「Safety Journey」(水 diff)。TLE 解は以前からできていた。N と M と K の上限が 5000 のときに O(K(N+M)) は Ruby にはたいへん厳しい。しかし不可能ではないみたいで、Ruby によるすべての提出を見ると AC が3つある。1つは numo/narray を使うもので、2つはループ展開した文字列を eval するもの。そんなテクニック初めて見たよ! 横目でちらちら見ながらまねしてみたけど、なんでか同等の速度は出なかった。繊細なのね。■提出 #33540024 (AC / 1981 ms)。まねできなかったからこれは正統派のコード。原型は以前からあった。ポイントは K のループがおよそ K/2 回というところ。定数倍2分の1。コードテストで実験して確かめたんだけど、13,14 行目を多重代入にして1行にまとめると 10 ms ほど制限時間をオーバーする。d1.values_at(*vs).sumvs.sum{|v| d1[v] } だともっとオーバーする。頂点ごとにまとめた辺(E)の代わりに辺の集合(UV)をそのまま使うと制限時間を数倍オーバーする。色々な積み重ねの上できわっきわの AC なんだ。


2022年07月24日 (日) [AtCoder] 精進。第2回PAST-O「可変全域木」。最小全域木に余分な辺を1本足して代わりに不要になった辺を取り除くと重みの和がどうなるか。まず、木に辺を1本足すと木はループを1つ持って木ではなくなる。不要になる辺はループを構成する辺のうちのどれか1本。追加した辺が頂点 A と B を結ぶなら、取り除ける辺は A と B のパス上の1辺。そのうち重みが最大のものを取り除けばいい。パス上の最大コストの1辺を効率良く探す方法は? ダブリングで A と B の LCA までさかのぼるついでに見つけましょう。■提出 #33481914 (AC / 1107 Byte / 669 ms)。去年はまだ解けなかった>WA。これで第2回はコンプリート。第10回まであるなかで初のコンプリート。自分のすべての提出


2022年07月23日 (土) [AtCoder] 今日は ABC261 があった。E までの5完だったのに2連続爆死したあとのレートをさらに下げてくるとは思わなかったよ。コンテスト成績証 - AtCoder。F 問題はデータ構造でなぐるだけの問題だったので終了後に AC をとっておきました。D と E の方が難しかったんだよなあ。それなのにそれぞれ緑下位、水下位の難易度評価なんだよなあ(つまりみんな解いている)。E 問題にはスマートな解き方があるみたいで、自分のは 1410 ms かかってるけど3桁 ms で解いているのが目印>Ruby による E 問題へのすべての提出。ビットのスタートが1の場合の累積結果と0の場合の累積結果を分けて 30 ビット並列で計算しておいて、初期値& で初期値が1のビットに対応する累積結果を取り出し、~初期値& で初期値が0のビットに対応する累積結果を取り出すみたい。実際、初期値2種類、出力2種類の4通りしか考えることがない単純な問題なんだよ、本来は。自分の提出 #33472932がなんで実際のビット演算をする代わりに :nop, :zero, :one, :flip という疑似演算子を使っているかというと、初期値のビットが1の場合と0の場合の2種類のケースを分けて準備すればいいということに気がつけなかったから、0が来ても1が来ても1つのデータで両対応できるように、疑似演算子を操作して実際の演算を遅延させるしかなかった。疑似演算子だから 30 ビット並列でまとめて計算することもできなかった。不思議だね、愚か者は自分で問題を難しくするんだね。そして本当に難しい問題は自分が理解できる程度まで過度に単純化して間違えるんだよね。度し難い。