/ 最近 .rdf 追記 設定 本棚

脳log[2022-08-07~]



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 ビット並列でまとめて計算することもできなかった。不思議だね、愚か者は自分で問題を難しくするんだね。そして本当に難しい問題は自分が理解できる程度まで過度に単純化して間違えるんだよね。度し難い。


2022年07月22日 (金) [AtCoder] 精進1。ABC260-F「Find 4-cycle」(青 diff)。2か所で「鳩の巣原理」のヒントを見てすぐに目を逸らすということをしていた。それが2、3日前。ヒントがあっても今日までかかった。■提出 #33392687 (AC / 335 Byte / 1597 ms)。一方の独立集合(V2)のサイズが意図的に小さく制限されているのはすぐに気がつく。これは要素でペアを作って1つ1つ調べても間に合うサイズ。つまり鳩の巣というのは V2 の要素のペアであり、ここに何かを詰め込んでいってあふれるのを待つ。それが何か。V1 の要素しかないんだけど、V1 の要素と V2 のペアを結びつけるものがしばらくわからなかった。目の前にきちんとお膳立てされていないとわからないんですね。辺をグループ化してグループ内で組み合わせる。■■■精進2。ABC132-E「Hopscotch Addict」(ギリギリ青 diff)。気がつけばなんてことのない問題。BFS をケン、ケン、パで3倍頑張るだけ。提出 #33383061 (AC) ■■■精進3。精進1の関連ツイート「アライグマ「F問題は鳩の巣原理なのだ! 類題は第一回最強コン決勝A問題『Equal Weight』なのだ! https://t.co/3KBTMkCrt1」から第一回日本最強プログラマー学生選手権決勝-A「Equal Weight」。制約を見てびびる。ネタもシャリも最大 20 万種類あるから、ネタとシャリの組み合わせも、ネタとネタ、シャリとシャリの組み合わせも1つ1つ取り上げるわけにはいかない。これが 300 点問題?■提出 #33398275 (AC / 238 Byte / 498 ms)。がんばって鳩の巣を探しました。重さの散らばりが 1 から 100 万のあいだだから、組み合わせた結果(ふたつの和)は 2 から 200 万のあいだに収まる。ネタとシャリを組み合わせて重さをキーにして記録していくと、最大で 200 万回書き込むまでには重複が見つかる。■掛け算の組み合わせだと 20 万は大きすぎる上限だけど、足し算だと 100 万でも現実的な数字だというのが、見た目通りではなくて意外性があった。ヒント無しでは解けなかっただろうね。■■■精進4。ABC254-D「Together Square」(緑 diff)。自分の頭からは TLE 解しか出てこないので見ました。「AtCoder Beginner Contest 254 D - inamori’s diary」 わっかりやっすーい。■提出 #33413694 (AC / 1545 ms)。prime_division を使った愚直解。遅いけど制限時間内ではある。■提出 #33414040 (AC / 190 ms)。さっきの提出は 1 から N の数について独立した処理をしていた。処理の連続性をいかして、配列をメモに使って、時間コストをケチると 8 倍速くなった。■Ruby によるすべての提出を見ると最速は 62 ms だから、まだ削れるはずなんだよね。わからんけど。しかも 62 ms のうちほとんどがインタープリタ起動にかかるオーバーヘッドだから、見かけ上の3倍差よりずっと効率が違う。


2022年07月21日 (木) [AtCoder] 精進。ABC260-D「Draw Your Cards」(緑 diff)。20220719に書いた。「D 問題が解けなかった3完」「まだ解けないよ」「解けずの緑になりそう」「LIS をやりながら配列の中間削除を繰り返す愚直解法しか思いつかない」 ところで、コンテスト中の一番最初の提出 #33313999 (RE) の冒頭には BIT が貼り付けてある。だけど結局一度も使わずに LIS に流れていった結果どこにも辿り着けなかった。■提出 #33376903 (AC / 1129 Byte / 863 ms)。やっぱり BIT やったんですよ。むしろ配列の中間削除を繰り返すしかないような平衡二分探索木向きの問題に使える道具は、BIT か平方分割(?)くらいしか持っていないのですよ。■Ruby によるすべての提出を見ると、最速級が 300 ms 台に集まっている。読むと、Array#delete_at を繰り返しながら LIS をしているような……。解法が少なくとも2つあって、どちらの方法もよく知っていて、それなのに今日まで AC に辿り着けなかったってどうかしてるよね。■解けるはずの問題を落として一時的にレートが下がるのはまあいいんだよ、どうせ戻るから。でも上に上がる人というのは、多少の取りこぼしがあっても(なくても)難しい問題を解くことで飛躍していっている印象がある。600 点問題、700 点問題が全く解けないことの方が問題。……というように口先だけでわかったようなことを言いつつも、解けるように具体的な行動を積み重ねていったりできないのが、自分を含む一般人のあり方だと思います。 たぶん、そのうち? いつの間にか解けるようになってたりするんじゃないかな? AtCoder に関連して流れてくる「目標はあれとそれ、今日はこれをやる」みたいなのは異常者のツイートなので、真に受けて立派な人間になるんじゃあないよ。


2022年07月20日 (水) [AtCoder] 精進。第2回PAST-M「食堂」。周期にそって数を数える問題。しかし問題文の長さパラメータの多さからわかるように間違えずに数えるのが非常に難しい。制約が厳しいので素直で間違えにくいが遅いやり方をすることもできない。■提出 #33368195 (AC / 550 Byte / 423 ms)。4、5時間がかりの力作ですよ。初日から最初に好物が食べられる日までのあいだに好物でないものを何皿食べるかを数え、最初に好物を食べたら D 日のサイクルのあいだに何皿の好物とそうでないものを食べるかを数え、余った1サイクル未満の皿数に何皿の好物が含まれているかを数える。前半で累積和を作り、後半で数える。累積和では好物と好物のあいだに何皿の好物でないものを食べるかを記録した。■サンプルしか通らなかった提出 #13619835 (RE×1/WA×3/TLE×24) を書いた2年前より確実に前進しているね。たとえこの前の ABC が3完であり下手をすると AtCoder を始めたばかりの数年前に劣るパフォーマンスだとしてもね。■この手の問題はこれまでに少なくとも3問解いている。ABC175-D「Moving Piece」と ABC241-E「Putting Candies」と ABC258-E「Packing Potatoes」。どれも水 diff。


2022年07月19日 (火) [AtCoder] 精進。日曜日にあった ABC260-E「At Least One」(ギリギリ青 diff)。D 問題が解けなかった3完なので E も F も問題を一読して解法の見当がつかないことを確認しただけで終わっていた。■提出 #33354142 (AC / 410 Byte / 456 ms)。見当がつかないとは書いたけど尺取りの雰囲気は十分に漂っている。始点を決めて、N 個の条件を満たすまで範囲を伸ばす。一度条件を満たせばあとはどれだけでも伸ばすことができるけど、始点が後ろにあるほど長さの上限が低くなる。提出したスクリプトでいうと I = Array.new(M+1){[]}T = [0]*N というデータの置き場所を用意したところが解法の8割。それぞれ、I が Ai や Bi といった 1..M の範囲の値から i を逆引きするもので、T が現在の尺取りの範囲が何種類の条件を満たしているかを数えるための 0,1,2 の3値の配列。■Ruby によるすべての提出を見ると、最初の提出 #33313831がコンテスト中唯一の AC だというのがすごいね。中身を見ると構成も記述も自分の提出とそっくりで驚く(Ruby で青色になるような人でも for ループ、while ループ、if 式をばりばりに使う手続き型のコードを書いてたりするんだ。そういうのはだらだらとまとまりがなくて読むのがつらい)。自分も時間内に書けて然るべきなんだよなあ。■D 問題「Draw Your Cards」は緑 diff だったみたいだけど、まだ解けないよ。土曜日の緑は昨日(20220718)片付いたけど、こっちの緑はこのまま解けずの緑になりそうだよ。LIS をやりながら配列の中間削除を繰り返す愚直解法しか思いつかないよ。


2022年07月18日 (月) [AtCoder] 精進。ARC144-B「Gift Tax」(緑 diff)。AtCoder Problems に Easy 問題を推薦してもらったら出てきたんです。まだ解いていない緑 diff はどれも解こうとしたけど解けなかった問題として名前を覚えてるんだけど、これは見覚えがなかった。■提出 #33348708 (AC / 177 Byte / 1181 ms)。おとつい1時間溶かして解けなかった問題じゃん。そのときも二分探索は書いていたし、A と B で割る二種類の割り算も書いていた。でもサンプルの4が合わせられなかった。なんで今日は AC なんだろうね、不思議だね。■まじめに書くと、おとついと今日では二分探索で探ろうとしていたボーダーの意味が違う。おとついはいったん増減の幅が a,b に固定されていることを忘れて、a 対 b の比率を保ったまま定まる平均値を求めようとしていた。でもそこから答えに近づけなかった。今日はまず、答えとなる最小値を二分探索で決め打ってから、必要となる数列を増加させる回数を求め、同じ回数を減少させるときに数列が維持できる水準(どの値より上を切り捨てるか)を二分探索した。2つの二分探索による2つの水準が逆転するならそれは矛盾であり答えとして成立しない。この考え(ARC144_b_TLE.rb27)は間違いではなかったけど、二重の二分探索に線形時間のスキャンが重なるので数十秒の時間がかかって TLE が必至。AC 提出は log を1つ外そうと最適化した結果であり、最初からあの形が頭の中にあったわけではなかった。直接最適な答えが導き出せないあたり、力が及んでおらず本番で解けないのも仕方のないことかもね。