/ 最近 .rdf 追記 設定 本棚

log[2024-07-27]



20240727() [AtCoder] 今日は日本レジトリサービJPRSプログラミングコンテ2024#2AtCoder Beginner Contest 364があった先週(20240720)と似たようなことを書いてもいいかなRuby にとっては D 問題が難しすぎて TLE が解消できなかったDF を見比べてF の方に見込みがあると思って F 問題に8割方集中していたが時間内には解けなかった終了 11 分後に F 問題の AC が出たあとちっとで解けたと思えばこそ得点にならなくてくやしいAGlutton Takahashiサンプルの2で示されているのは親切だけどそこそこ殺意の高い罠がありますね全部食べたあとで気持ち悪くなるパターンがある。sweet\nsweet を検索していたのを修正して sweet\nsweet\ns を検索するようにしたBGrid Walkやります。B 問題にしては実装が重めグリドのサイズが小さくても実装量が減るわけではないんだよね当たり前だけどそこんとこ承知してくれているかな?CMinimum GluttonC 問題で DP か? と一瞬身構えたけど最小値を求めるということで2通りの貪欲法を比較するだ大丈夫です最大値を求める DP 問題は E にあります。DK-th Nearest二分探索してくださいという問題にしか見えなくて他に方法が思いつかないんだけど制限時間3秒のところ(1割増しの 3.3 秒ではな) 3.22 秒かかって TLEったので220 ms ほどの高速化が必要どうするの?EMaximum GluttonC 問題の難しい版甘さとしっぱさの組み合わせを状態のキーにはできないけど甘さとしっぱさのどちらかと個数を組み合わせてキーにすることはできる甘さをキーの1つにしたらっぱさを最小化する DP をするこれもサンプルが教えてくれたんだけどA 問題と同じ罠があります。同じ罠に落ちかけましたFRange Connect MSTどういう風に辺を引くことになるのかイメージがしづらい木なので本数は N+Q-1 本だと決まっているそれを最大 N×Q の組み合わせからどう選ぶと全域木になるのあれこれ考えてようやく納得できたのはi=1..Q においてLi..Ri のあいだに連結成分が g 個あるならg 本の辺を引くのだということ両手の 5+5 本の指を使って考えるとそれで N+Q-1 本の辺が選ばれるようだったのでそう思った答えが合わなくて時間内に提出できなかったんだけど原因がしょうもなくて貼り付けた BIT のイニシャライザにある初期化コドが今回は不要だと思って削除したけど削除してはいけなかったというそういう理由で答えが合わなかったたとえばヒープだとト済みの配列を内部データにする場合初期化の必要がないト列はそのままでヒープの要件を満たしているだけど BIT の内部データは違うんだなあ解ける問題だったなあ1から数年前の自分なら解いていたなあ自分のすべての提出最近ユーザー名の横に表示されるへの字ノイズではあるんだけど水色でもまだ 1500 台を維持しているなという慰めにもなっているもよう■精進D 問題Q のループの中で二分探索をする中で二分探索を2回行って TLE を出していた二分探索の上限を指定せずに TLE×11上限を指定して TLE×7最も内側にある2個目の二分探索を省けるときは省くようにして TLE×1最内の2個目の二分探索を完全に省いて ACこれが 1765 ms なんだけどRuby627 ms で解いている人がいるんだよね気になるけどネタバレは嫌だD 問題別解。提出 #56088391 (AC / 325 Byte / 340 ms)log 1つでできると読んだのでk 幅のドウを二分探索で置いてみた判定条件は右端の要素が初めて左端の要素よりも b から遠くなる瞬間そのひとつ手前では逆に左端の要素が右端の要素より b から遠くなっているこの両者を比較する二分探索の高速化っていうと尺取りが定番なんだけどだから昨日はその方面で TLE 回避策を考えたりしてたんだけどこの D 問題はドウの幅 k がクエリごとに可変だから尺取りはうまくない今日の提出では同じ二分探索を使っていてあまり違いを感じないんだけどよく見れば二重の log が一重に減っているlog 1つの差ってたしかにこれくらい微妙なものではあったPairs を解いていたときに書いているlog ひとつの差ってちっとした違いなんですよっと見る角度を変えるだけ提出したあとでもういちどさっき読んだブログを読み返すとまんま自分の提出がやっていることが書いてある初めて左端のが遠くなった場所を見つけてその一つ前(存在すれば候補なので比較してなんかよくわからんなあと思いながら読んでいたけど実際今「自分より1離れたもの同士を比較「長さが1短い区間を考えて「初めて右のが遠くなったら左のを付け加えてそれがそのまま答えとかよくわからないんだけど必要なことは一度読んだだけで頭の中に入ってるんだな! 自分では思い出せないだけで


20240720() [AtCoder] 今日は AtCoder Beginner Contest 363 があったRuby にとっては C 問題が難しすぎて解けなかったが AC を出している人もいる精進が足りないRuby で通している人が1人でもいるなら自分も通せなければいけないなんなら自分が最初で唯一の AC でありたいE まで解いてから FC を見比べて F の方に見込みがあると思って F に専念していたその見込みは間違っていなかったがTLE を出したあと誤った解法の実装にのめり込んでいる内に時間切れになった実は関数に引数を1つ付け加えるだけで AC になったのだが30 分ちかく時間を残していてそれに気がつけなかったくやちいAPiling Up全パターンの差分を並べてもっともふさわしいものを選んだ短い解答を見てみるとすべての基準値が 100 の倍数だということを利用していたそういう法則がすぐに見抜けないし見抜けるまで問題を読んでもいないBJapanese Cursed Dollトして P 番目なんだけど昇順ソトして前から P 番目ではないそれを間違えていてもサンプル3を試すまでは答えが合うのが怖いCAvoid K Palindrome 2順列全列挙では間に合わなかったどうやるの? C 問題で順列全列挙以外はやる気がないよDPalindromic Numberこれぞ ABCD 問題diff って感じの問題実際の難易度が何色かはまだ知らないけども順番に生成して 10^{18} 番目まで数えることはできないのでまずは桁数を決めて桁数が決まったら先頭の桁から確定していったESinking LandUnionFindす。最大6桁の数字が 100 万個という入力はそれだけでけっこう重い処理正確さを重視して富豪的に書くと ACTLE のボーダーを超える可能性があるので全体を通して最初から書き方を選んでいく……余裕があるといいね! グリドの各マス+海用に1個の頂点を用意して海抜の低い順に自分より低い頂点とのあいだで結合する海のマスを数えたら陸のマスが求まるFPalindromic Expressionやるだけの問題だと思うんですよ解けたはずだと思えばこそ悔しいまず中心に N を置きます。これが最初から条件を満たしているならこれが答えさもなければNL*M*R で置き換えるLR は左右対称でなければならずM に対しては再帰的に同じことを繰り返す。2数の積で N を割っていくのでN10^{12} だからL,R として列挙する数は 10^6 個程度に収まって許されそう終了条件を N<[L,R].min**2 として愚直にやったら TLEったNM に関して結果をメモしたら数は減ったけどまだ TLEったAC になった鍵はA*B*C*D*E という状況で A<=B でなければならないと定めたことこういう方針自体は TLE が出た直後に考えて実装に取りかかってるんだけどなぜか実装の途中で L が回文数でなければいけないという条件が加わっていてその実装に忙殺されてしまっていたなんでだよ自分のすべての提出F 問題日記を読み返す「なんでだよの答えが見つかるんだよなあL*M*RLR に関してLR は左右対称でなければならずと表現しているところに誤りの種がある左右対称なのは L*M*R 全体なのであってLR について書くなら表現を改めてLR は反転して一致しなければならずとする方がよりふさわしいと思う雰囲気で理解して細部がぼんやりだから途中ですりかわるんだよコンテキトが遠ざかったときに左右対称という断片に引っぱられて勘違いをする■精進C 問題Array#permutationN の階乗通りを列挙する代わりに再帰関数で同じ文字を区別しないで列挙するようにしてもまだ TLEった(#55827067)X で読んだ通りに1度しか出現しない文字を統合する前処理を施すことでさらに列挙数を減らすことができて AC になった。提出 #55827317 (AC / 536 Byte / 584 ms)300 点問題にかけていいコトではない同じ時間で DEF を解いたあとで初めてペイするD 問題N=19999のとき正解が99999999(8)だけどコドが出す解が9999999(7)になっちゃうみたいですが通りはしましたと投稿している人がいて試しに自分の AC 提出(#55797000)を実行してみたら 100000001 () になってどちらでもなかった投稿主の提出(#55831310)をコドテトで実行してみたらたしかに書いてある通り7桁の9が出力された正しい答えはなんなんです? RubyAC 提出23個で多数決をとったら正しい答えは 99999999 () らしい入力と出力の見た目には桁数が違っても維持されるパターンが見られるのだけど自分の提出は N=100000 型とか N=999999 型では他と一致していてもN=19999 みたいな型の入力に対してはずれているって N=199N=200 の答えが同じなんだもんサンプルの3を合わせるために ≦ を < に修正してから提出したのだけどたぶん修正すべき場所が間違っていたザルなジッジにお目こぼしされてしまった提出 #55833437 (AC)after_contest はまだないみたいだけど修正版を提出N=19...9N=20...0 っていうのは出力の桁数が変化するという点でのコーナーケースみたいトケースにコーナーケースがなかったんだねE 問題別解。提出 #55860799 (AC / 523 Byte / 707 ms)UnionFind 解が #55800705 (AC / 524 Byte / 1629 ms)ったので長さはほぼ同じなものの時間は倍以上早くなった別解は BFSプライオリーすら必要ではなかった■精進砂の城 (Sandcastle)E 問題と似た問題だと名前が挙がっていたので。提出 #55862476 (AC / 354 Byte / 578 ms)たしかにこれも BFSったかなりシンプルに書けたと思う


20240717() 二三日は何日なのか問題もちろんこれが問題になったことはない自分としては四六時中や四十九日七十五日三々五々から演繹するとニサンニチになるしかないと思うのだけど実際にそうだったことがあるのを知っていることからもそう考えるのだけどATOK で明鏡国語辞典を引くしじゅうく‐にち【四十九日】〘名〙 人の死後四九日目に当たる日またその日に行う法要七七日(しちしちにち)とか書いてあってこれもうわかんねえないやホトはわかりますよ「四十九日「七七日の2つ「四九日()とでは使用時期にずれがある辞典の言葉は収録される言葉よりも新しい23 日を二三日と書くことの帰結として10 月が一〇月になっていたのが先々週読んでいた小説何を今更感しかないけどもそうなんだそりゃそうなるよなだけど気持ち悪いなその○はなんなんだ漢字ではないよなとひっかかってしまったのが今日の日記になっている十月って書きたいよATOK10 を変換して出した一〇で使われているのは○ではなかったU+3007 「漢数字ゼロ IDEOGRAPHIC NUMBER ZEROでありU+25CB 「丸印,白丸 WHITE CIRCLEとは異なる文字だった〇が比較すると新しい字だけど数百年はさかのぼれるみたいなことが Wikipedia の漢数字のページに書いてあるお前漢数字なの漢数字とアラビア数字を区別して一方では位取り記数法を認めたくないっていうのは単に好みや慣れや旧弊に囚われているってだけなの自分はこれからも区別して用途を分けていきます。■用途を分ける(漢数字では位取り記数法を使わない)ことの別の一面は「健康第1「3位1体「別の1面とは書かないということ算用数字を使うのは13と数を数える場面だけでいいXX+1 が可換な場合だけでいい


20240716() 子供の頃にスーパーボールで遊んだ記憶今でも理解できないし説明できないのだけどたとえば床に2バウドさせて壁にぶつけるとする1バウドした位置から A の距離で2バウドしそこからさらに B の距離で壁にぶつかるとするこの AB の距離(あるいは時間)の比率が跳ね返ったボールの跳ね方に反映されて不等間隔の規則的な跳ね方を繰り返す。ったよね? おもちゃにも流行り廃りと技術や素材のアップデトがあって今の子供はスーパーボールなんかでは遊ばないかなあと思ったので書いた


20240713() [AtCoder] 今日はトヨタ自動車プログラミングコンテ2024#7AtCoder Beginner Contest 362があった特に書くことはないけども参加記録として。自分のすべての提出ABuy a Pen3通りなのでどうとでも書きます。BRight Triangle2乗のまま整数のまま三平方の定理で判定します。CSum = 0最初はすべて L に寄せて和の最低値を求めます。あとは和が負である限り各組 R-L を上限として右に寄せていきます。DShortest Path 3辺だけでなく頂点にも重みがあって何かが変わるかなと考えたけど普通に普通のダイクトラ法のままだったECount Arithmetic SubsequencesN の制約が 80 以下と非常に小さいこれだけ小さいと O(N)O(logN) の差よりも定数倍の違いの方が大きくなりがち80 の3乗が大した大きさでないことを確認して愚直3重ループを書いたら TLE が出てびっくりした3重ループと書いたけど実は3つ目のループは再帰関数の中に隠れているそれって3重にとどまらないのでは? やばいのは公差が0のケースなのでそれだけ別で数えて ACFPerfect Matching on a Treeッチングとかフローとか辺被覆とか点被覆とかはわかりません「最大重み最大マッチングてなんだったんでしょうまんま「知らないキーワ怖いG 問題に流れていっちったけどこの問題は難しいことは考えずに木の中心で頂点集合を2つに割って組み合わせたらどうかなと思ったWAったこの問題の何が問題なのかがわかっていないかうまくできなかったかどちらなのかもわかりませんとはいえうまくできていなかったのは間違いない中心に頂点があるとして中心から3本以上の辺が出ている場合が考慮できていなかったGCount Substring Queryミシシッピの s が足りないのが気になってしょうがないなんでコンテト中に辞書を引いてるんだ……F 問題より見込みがあるかと先に考えていたけど数を数えようとするとどうしても2乗の時間がかかりそうになる接尾辞配列を使うだけみたいなツイ()を読んだその使うだけもできないのだから惜しくも悔しくもないけども接尾辞配列とか完備辞書とか Trie とか見て見ぬ振りをして実装せずに来たツケなのは間違いないSA-IS 法のメモ - まめめも8割くらい読んだしれっと挟まれた翻訳者自らの宣伝だけどその本はもう持っている悲しいかな理解が追いつかなくて積まれているけどもSA-IS 法に話を戻すと2割が完遂できなくて写経することしかできないたとえ写経でもするべきなのかなあ(やらないつもり)やると書いてやる有言実行メソドとやらないと書いてやる天邪鬼メソドの両方があります。自分のモチベーションをより高める方を選んでどうぞ■精進F 問題。提出 #55644781 (AC / 1365 Byte / 636 ms)やりたいことのイメージは合ってたみたい中心で2つかそれ以上の頂点集合に分けて異なる集合から1つずつ選んでペアを作るそれをどうやってうまくやる葉から処理を始めて親にどんどん頂点集合を集約していくその集合の大きさが過半数になってはいけない最終状態がいくつか考えられるわかりやすいのが集約された結果ある頂点とその2つの子が残りそのサイズとつながりが (N/2)-(1)-(N/2) である場合左右の子から1つずつ頂点を取り出してペアを作ればいい総頂点数の偶奇により中央に頂点がない (N/2)-(N/2) のパターンも考えられるがやることは同じもうちっとわかりにくいのはある頂点が3つ以上の子を持っていてどの子に軸足を移そうとしてもその瞬間に他の子が過半数の大きさの頂点集合を作ってしまう場合最も単純なケースは2から N のすべての頂点が頂点1につながるスター型のグラフ頂点1を中央に据えて他のどの子の頂点集合もサイズはたったの1だけどどの2頂点もマージできないそんな感じで頂点集合をマージできるだけマージして残った頂点集合の集合からペアを作るのが次のステップ同じ集合の中からペアを選びさえしなければいいだからプライオリーを使ってサイズの大きい頂点集合から優先して2つ選んでペアを作ることを繰り返したっと洗練されたうまいやり方と考え方が絶対にありそうだけどAC なんやしまあええやろ(向上心のない怠惰な態度)あと自分が中心と呼んでいるものに重心という名前がついているらしいのは何か所かで読んで把握しているF 問題。某週記を読みまして DFS 順でペアが作れると知ったDFS の行きがけ順(に限らない?)27 個ないし 26 個の頂点を A-M$N-Z と並べたなら、(A,N),(B,O),(C,P),...,(M,Z) のペアを作る(のだと思う)ーカリに注目すればなんとなくそれでいいような気がするし逆に両端からペアを作っていくのがダメなのもわかる気がするがいつでも絶対それで OK とはわからない■自分の解答の後半のステップはプライオリーを使わないで単純に入れ子配列をフラトにして真ん中で切ってペアを作るので良さそう(C.flatten!; C[C.size/2..].zip(C))どの解説もそういうペアの作り方をしてるのでどの頂点集合も過半数に届かないようにしているのだからたしかにそれで同一集合からペアを作ることはないみたいそれとDFS での頂点の並べ方は帰りがけ順でも OK と解説に書いてあった


20240712() PS5 のコトローラって臭くなりやすいと思う手に汗握る状況が多いというのが根本にあるとしてもPS4 まではコトローラーが臭いとかコトローラーを握っていた手が臭いとかが気になったことはなかったッシュでよく拭いてリセトしても数日で臭くなる材質かな表面処理かな何が違う?


20240708() 先日自転車のハドルを掴み損ねて上半身から地面にダイブした雨の日で手袋をしていたので手は平気手袋も無事ズボンの膝がちっとほつれてるけど穴は空いていない一番のダメージが肋骨にある指で押さえると痛む場所が1か所特定できるだけなのだけど肋骨の痛みによる QOL の低下が著しい咳をすると痛む深呼吸をすると痛む布団でうつぶせになると痛む日常のささいな何かしらの行動に対するリアクションとして痛みが発生することのなんと不自由でうっとうしいこと年を取るとたんが絡むんですよ若い子みたいにのどの奧がつるっとしてないんで咳払いでいっときの疎通を確保しようとするたび肋骨が痛むつら「雨の日で手袋をしていたのでと書いたことについてまぎれもない事実なのだけど雨の日でないなら手袋をしていないという裏読みをさせてしまうとしたらミスリングであるある命題の真偽と裏の真偽に関連はないのだとしても誤解がないように書くと雨の日だから雨用の手袋をしていた(晴れの日は晴れ用の手袋をしている)どちらも手のひらは革で丈夫「手のひら以外は革でないという裏読みをしたなら半分間違っている


20240706() [AtCoder] 今日はデンソークリエトプログラミングコンテ2024AtCoder Beginner Contest 361があった。自分のすべての提出AInsert問題名の通りに Array#insert を呼び出す。いつまでも引数の順序が覚えられないメソ今日はリファレスを引くのも面倒がってテーに位置と値を並べて呼び出して結果を確かめたBIntesection of Cuboids現在は修正されているタトル名のなごりが見える(「テセクション)コンテト中に気が付かなかったのは不覚というほかない誤字脱字はかなり神経質に駆逐したいタイプなのでさて本題頭で立体交差を想像するのは難しいけどもこれは1次元の交差を3回確かめるだ制約を確かめてからトしたりイコールの場合を考慮したりしたけども今改めて制約を見るとちゃんと不等号で大小関係が規定されていた目がついていない言い訳をすると同じ範囲の制約がたくさん並んでいたからすべての入力値が範囲内で無制限の値を取るのだと思ったのだった6つも 12 個も同じようにたくさんでしょうよ目がついていないのと数が数えられないのとどちらがましか言い訳になっているCMake Them Narrowトして最小値を決め打つ。Array#each_cons がおそらく線形時間を要するせいで TLE を1回出したたしか以前も同じメソドで TLE を出している学習しないなだけども配列の dupshiftpop では配列の要素レベルのコピーが抑制されると知っているから配列から固定サイズの部分配列を切り出すのに単位時間しかかからないと期待するのは当然じゃない? each_consArray#each に基づいて実装されてるとしても一度の each_cons 呼び出し(と複数回のブロック実行)で線形時間しかかからないなら TLE にはならなかった尺取りをするなら TLE にはならないブロック実行のたびに線形時間かかっていてeach_cons 全体では2乗の時間がかかっているからこそ TLE になるこれが予想外DGo Stone Puzzle制約がごく小さいのでメモして BFS をする実装でいろいろミスをしたたとえば (1,2)(3,4)(5,6) みたいな (奇数番目,偶数番) のペア単位でしか交換できないと思い込んでいたりそこはちゃんとサンプルで落とされたけども見るべき要素数が N ではなく N+2ったりも15 分かかったETree and Hamilton Path 2ARC179-D Portable Gate の簡単バージョン精進記録はこちら>20240602根を決めて DFS ですべての頂点を訪れてまた根に戻ることを考えるとすべての辺をきっちり2度ずつ通るのでコトの上限がまず決まる本問題では根に戻る必要がないのでどれだけのコトが節約できる直径自分の提出がすでに求まっている直径を再帰関数で改めて求めているのは紆余曲折の結果なのです。引き算で求めるのではなく2種類の再帰関数で積算して答えを求めようと迷走していたなごりプライオリーを貼ったけどいらなかったらしい根からすべての頂点への距離を求めているのだし各頂点へのパスは1つだけなのだからそれはそうFx = a^b苦手な苦手な数学問題指数を3以上に決め打つなら N 以下の全ての立方数4乗数5乗数(って呼ぶのか知らないけども)……を列挙して重複を排除できるゃああとは最大で 10^9 個ある平方数をどうやって数えるかだすでに数えた立方数4乗数……が平方数でもあるかどうかを確かめて重複を除外することでクリアしたこの問題の提出でも自分は変なことをしているb を固定したときの a の最大値を Math.log で求めてからすべての a^b を列挙してるんだけどそれだったら a=1 から始めて N<a^b になるまで a+=1 を繰り返せばいいコンテト中はそこまで頭が回らないんだなあGGo Territory解けてないよサンプルにあるように囲われている格子点を数えたい縦横斜めに並んだ石のあいだで UnionFind をしてまずは輪っかを作っているかもしれないグループを特定した次にグループを構成する石の周囲8マスから BFS を開始して孤立している格子点の島を数えようとしたどこで探索を打ち切るグループを構成する石の X 座標 Y 座標の最大最小を限度にして BFS を打ち切って孤立していないと判断をしたこれでサンプルは合ったけどWA があるかもそうだけど TLE は間違いないと思うんだよなあおおざっぱに2乗の範囲を塗りつぶそうとしてるわけだからコンテト成績証黄パフォに限りなく近いいいパフォが出たけども前回(ABCUnrated 判定だったので配点と Writer から必敗を覚悟して出た ARC)の緑パフォの傷が癒せただけなんだよなあF 問題まで4桁人数が解いてるので早解き回だったみたいそれは配点からも読み取れる簡単な問題に滅法強いという自己評価を裏切らない結果G 問題自分のやり方で WA になる例ープが2つ左右にくっついていて右のループの周辺ということで右のループの外側左のループから見れば内側から BFS を開始した場合打ち切るタイミングを誤る盤面を BFS のたびにクリアすれば解決するけどますますもって TLE が加速する■精進G 問題。提出 #55351016 (AC / 796 Byte / 571 ms)kotatsugame さんの動画(【競技プログラミング】ABC361【実況】)で解法を聞いたんですよUnionFind をするのは石と石ではなく縦もしくは横方向に連続した格子点列の隣り合ったもの同士だったってることは難しくなくて付加情報として格子点数を持った UnionFind だけど頂点番号が与えられているわけではないので格子点列に自分で番号を割り振らないといけないひと手間がやっかいY 座標列をソトし忘れたりひと手間に色んなミスがからんでくるグループの管理と格子点数の管理を同時にやろうとしてグループ0と数0を混同したりもしたまた格子点の総数が数えられなくて答えがなかなか合わなかったX 座標の最大値が 200000 だとして0 から 200000 のあいだには 200001 個の格子点があるんですよ(あたりまえ……ではなかったんだなあ)


20240701() [AtCoder] 精進昨日あった ABC360-ERandom Swaps of Ballsひとえにひとえにデバッグ力が足りなかったサンプルの2に 3 2 という入力例があるサンプル1のように解説がないし出力例が実数ではなく 554580198 (mod 998244353) だということで途方に暮れていたのが昨日だけどね自分で計算すればいいんですよ昨日の方針だけど場合の数を K 回数え上げていって最後に N^{2K} で割ることで確率に変換するようにしていたということは、3 2 という入力に対しては9通りの出目が2つ続く 81 通りの場合がうまく数えられていれば良かった81 に足りなければ遷移の式が誤っているということそのようにして今日はサンプルの2が合ったそして次のサンプル3の入力が 4 4これの答えがまた合わなかったのだけど同じようにして 4 2 に対する 256 通りの数え漏らしを見つけることでサンプルの3もまた合った提出 #55117837 (AC / 362 Byte / 126 ms)N=1WA を出さなかったのはすでに他所で知っていたから全く警戒していなかった■この E 問題までささっと解けてまだ不満というのが自分の現状認識なんだけどまた脳みそにクモの巣が張ってきてるみたい半年後からの挽回に期待!■続けて G 問題 Suitable Edit for LIS にも取り組んで提出したのだけど、#55121924 (WA×8/AC×45)WA になるケースが全く作れなくてデバッグが進まないC++AC 提出と答えを突き合わせたりしてるんだけど最初にコピーしてきた提出は長さ6程度のシッフルした順列に対する答えがおかしかったよ(それでも AC)2つめにコピーしてきた C++AC 提出とは意見の一致を見たので自分だけが盛大な勘違いをしているということはなさそうこんなザルなジッジだったら8個くらいの WA は見逃してくれてもええやろG 問題について現在わかっていること(あるいは勘違いしていること)操作によってできるのは LIS の長さを +1 することだ先頭か末尾の値を含まないで LIS が作れるなら先頭か末尾の値を操作して +1 できるでは先頭と末尾の値が LIS に不可欠だったら? 適切な位置に LIS に参加しない空き要素があるなら +1 できる適切とは? 空き要素があってもその前後にある LIS を構成する要素が連番だったら +1 できない条件はこれだけだと思うところで LIS って候補がいくつもあるのが普通最長の長さを知りたいだけならそれらを区別する必要がないけど今回は空き要素を挟めるか挟めないかがポイトなのでLIS の個別の列に踏み込んでいかないといけない添字列に対して LIS を求める操作をして作業配列を上書き更新せずに追記して履歴を残すようにしたらうまくできないかなーと思って書いたのがさっきの提出なにがうまくないのかわかんない思いつきでいけるやろって思う方がおかしいそう■通ったー!!! G 問題。提出 #55154669 (AC / 672 Byte / 277 ms)前の提出が 671 Byteった17 行目の <<= にすると WAAC になった狭義単調増加だから値の比較にイコールがないのは一見自然なんだでも 17 行目では LIS に含まれない要素をはじいていた。< の否定が >= であるようにそこではイコールが必要だったなんだ1文字かランダムケースの生成ルールを A = 1,*([2,3,4]*3).shuffle,5; puts A.size,A*' ' に変えたらすぐに見つかった同値の要素の重複がキーだったともあれやろうとしたことがちゃんと AC に繋がっていたのは良かったLIS の履歴の活用法について書く作業配列には通常長さ i の増加列の末尾の値を記録する最終的に i が取り得る最大値が LIS の長さ今回は値の位置も知りたいので値の代わりに添字を記録しさらに履歴も知りたいので各長さ i それぞれに添字列を記録していった入れ子配列の総要素数は N+(LISの長) になる作業配列には最長に届かなかった短いものも含む全ての長さの増加列の情報が記録されているこれを後ろから見ていくことで LIS の一部ではない要素をはじいていくことができる値を見ることで添字列の先頭から添字を見ることで添字列の末尾から取り除いていくことができるたぶんねあとは前後の添字列を見比べて LIS に中間値を挿入する添字の空きと値の空きがあるかを確かめる■遅れていたレト更新があったのだけどB 問題で範囲が間違っていた普通の WAドを投げた人が Unrated に不満を表明していたトケースの制約違反とは関係なく WAった人も Unrated なの? 確かめたら自分も Unrated で草4完低パフォだから不満はありませんけども1cw という範囲を添字にするときにc0 始まりにするのを忘れて各行1文字目を縦読みするケースが漏れていて WA を1回出したんだよね


20240626() 競プロ出身者の使えなさは異常■すごくありそうだなって思う全体から見れば一部だし界隈によらず存在する特性でもあるはずだけど特に優秀で他によりどころがない場合にああいう悪い感じに増長してしまうことはあるだろうなと思う競技プログラミングになじむ時点でその素養は高いかもしれないもちろん主語がでかいし偏見だし個人を見ろと言いたいしクソと言っている周囲がクソな環境にずぶずぶにつかったクソである可能性も常に考えている増長っていうか防衛にも見えるハリネズミ的な誰も認めないから主張が先鋭化するんじゃないの認めつつ穏当に導くこともマウトを取り返して黙らせることもできなかった結果ではないのなんにせよミスマッチはその通りお互いに不幸でしたね


20240625()

最終更: 2025-03-15T01:11+0900

[AtCoder] JOI Open Contest 2024 過去問A - 試験 2 (Examination 2)

いつもの前置き:提出先は AtCoder だけど問題は AtCoder の作成ではなく JOIだけど競プロカテゴリを意図して AtCoder タグを付けています。

しんどかったBC 問題を読むのは気が向いたときにしてA 問題についてだけ書く

 どういう問題?

4種類の論理演算(! & ^ |)っことある値を境にして真偽が切り替わる関数から成る式の値についてクエリに答える問題式の長さが 1M 文字以下でクエリとして与えられる値の数が 200K 個以下つまりどちらもとてもでかい

 アイデア1:クエリの並び替え

クエリを昇順に並べ替えたら入力値との比較で真偽が決まる関数というのは一度だけ false から true に値が切り替わる関数になる更新頻度が (関数の数)×(クエリの) から (関数の) に減る

 アイデア2:セグメト木みたいに関数の値の変化の影響範囲が対数レベルにならへんの?()

以上の2つのアイデアというか願望に基づいて最初に書いたのが次の提出

 提出 #54709820 (RE/TLE/AC)

関数を class で置き換えてそのクラスに演算子を定義して式全体の評価を eval で行うお手軽な実装

 RE の原因は Ruby が非ゼロの終了コドを返すこと

eval であるか *.rbァイルを実行しているかに関係なく大きな式を評価しようとすると Ruby は黙って異常終了する式の形によっては終了する前に nesting too deep (SyntaxError) というエラーが出ることもある。p 1^1^1^1^1^...^1 という 10 を表示するスクリトをコピペで膨らませて実行するとRuby のバージョンと Windows でのスタックサイズに左右されるんだろうけど手元では 7 KiB を超える前に何も出力されなくなった

 TLE の原因は願望が現実ではなかったということ

両極端の例を挙げると、1+2+3+4+5+6+7 という式を [+ [+ [+ [+ [+ [+ 1 2] 3] 4] 5] 6] 7] と解釈するとき、(1+(2+(3+(4+(5+(6+7)))))) という式を [+ 1 [+ 2 [+ 3 [+ 4 [+ 5 [+ 6 7]]]]]] と解釈するとき階層が直線的に増えていく

 対策1:逆ポーラド記法

中置記法とかっこの存在が式の扱いを難しくしている

変換アルゴリズムがうまく書けなかったので検索しップに出てき逆ポーラド記法入門2|中置記法から逆ポーラド記法への変換というページを参考にした

うまく書けなかった部分求めていた答えがまさ「演算子を全てpopしてと与えられていて喜んだのだけどあとになって答えが合わない原因「全てにあることがわかった上のページで扱っている四則演算のように演算子の優先順位が1位と2位の2つだけな「全てで正しいそれより多いなら「これから入れようとする演算子よりも優先順位が高い演算子を pop できる限り全てが正しい日本語の説明と Python の実装例に齟齬はなかったので日本語だけの問題ではないみたいその一部分を除けば文章だけでアルゴリズムの全体像がイメージできるわかりやすい説明ではあった

これで RE は解消するけど TLE はなくならないむしろ eval を呼び出してインタープリタに丸投げすることができないぶん遅くなる

 対策2(失敗)更新の伝播を下の階層から更新を階層ごとにまとめて

例えば [1]^[2]^[3]^[4]^[5] という1つの式があってクエリが 10ったとする最初は全ての関数が falseクエリの昇順に true に切り替えていく10 が最小のクエリなら1 から 10 までの関数を順番に true に切り替えていくのだけどその過程でこの式は false>true>false>true>false>true と値をチカチカ切り替えていくもしこの式の全体が別の式の一部分であるならそれら外側の式も同時に連鎖的に値を切り替えていくことになる

更新の伝播を階層ごとに一旦ためておいて深い階層から足並みを揃えて各項につき1度だけ値を更新しようとしたその過程で更新と更新が重なって更新が消えることも期待できるただまあこれは根本的な解決策ではなく効果がある入力もあるかもねというレベルの対策にすぎなかったTLE はなくならなかった

 対策3(失敗)式を真ん中で半分に

演算子の優先順位を考慮して、| ^ & の順番でっとも真ん中にある演算子で分割する

たとえば [1]&[2]&[3]&[4]&[5]&[6] という式なら [& ([1]&[2]&[3]) ([4]&[5]&[6])] と分割する

たとえば [1]&[2]&[3]&[4]|[5]|[6] という式なら [| ([1]&[2]&[3]&[4]) ([5]|[6])] と分割する

ところでこの分割は同一階層内でしかできないので、[1]&([2]&[3]&[4]&[5]&[6]) の分割結果は [& ([1]) ([2]&[3]&[4]&[5]&[6])] になるっこを無視して分割してしまうとあとでどうくっつけていいかわからないので

っこに制約されるということで更新が影響する範囲を対数レベルに抑えて TLE を解消する助けにはならなかった

 対策4(失敗)逆ポーラド記法の式を操作して同一演算をマージする

なぜか抵抗があって考えないようにしていたのだけどTLE 続きでなりふりかまっていられなくなったので結合法則を使う実は対策3でももう使っている

「なぜかっていうか左結合だと問題に明記されていたからそれを無視するのはずるであると理性ではなく感情が訴えるのだ答えが合いさえすれば何をしてもいいという教育は受けていないたぶんそういう理由問題の解釈が曖昧にならないように出題者が左結合だと定義するのはわかる交換して答えが変わらないのを見抜いて利用するのが解答者だというのもわかるだけど無意識が抵抗しているまあいいや

中置記法の式はかっこがあってややこしいので逆ポーラド記法の式を操作する

たとえば 1+2+3+4+5+6 を逆ポーラド記法に書き換えると、1 2 + 3 + 4 + 5 + 6 + になるのだけど演算順序をいじって 1 2 3 4 5 6 + + + + + に書き換えたい

そうすると何が嬉しい演算子に由来する階層を取り去って [+ ([1]) ([2]) ([3]) ([4]) ([5]) ([6])] と解釈することが容易になる次にこれを6項演算として扱うこともできるし2項演算のまま引数列を半分半分にしていくこともできる半分半分にするということはセグメト木のようにきれいで効率的な階層が作れるということ

正しい方向に向かっていることを予感させるけど1パスでやろうとして十分にマージできなかった

たとえば次の式の書き換えを考える。1 2 + 3 + 4 5 6 + + +参照範囲が限定できるので予め連続する演算子を結合しておくと便利。1 2 + 3 + 4 5 6 +++ になった左から読んでいって最初の + 演算子に出合うとき右の要素が被演算子(3)でその次の要素が + 演算子なら順番を入れ替えて 1 2 3 ++ 4 5 6 +++ にできるしかしこれ以上の結合ができない被演算子もまとめておくとひとつ飛ばすだけで +++ にアクセスできる? だけど 4 という項は 2 2 * という演算子を含む3項として存在していることもありますね

 対策5:逆ポーラド記法の式を解釈するときに同一演算をマージする

対策4とやりたいことは同じなんだけど今度はうまくできた演算子に行き当たったときスタックから取り出した2つの値(a, b)を即座に [op a b] としてスタックに戻すのではなく、ab が単独の値か何らかの演算の結果なのかを調べて可能ならマージしてできるだけ階層を増やさないようにしたそしてそれが最後でもなくスタックから取り出されてまたマージされることもある

 提出 #54933176 (AC / 2299 Byte / 1088 ms)

これの 92 行目から 107 行目のあたり

2Kーバーの長大なスクリトになってしまった絶対もっと短く賢く書けるはずでし

 っと読んだ


20240624() セルフレジであたふたしてる年配者を見るにあの手の人々「文字を読まないので文字情報は彼らには無力 - Togetter [ゥギッタ]■何度も利用しているスーパーのセルフレジに言いたいことがあります。セルフレジに2種類あるのねそれぞれに「こういうキッシス決済が使えます「キッシス専用です。現金使えませんとか書いてある一度間違えたからその次の機会にどこに注意していれば間違えずに済んだかという観点で注意を払って観察してみたことがある全然わからなかった2種類のセルフレジは大きく左右のゾーンに分かれていて待機場所も左右に隣り合った位置が別々に指定されているレジと列に違いがあると知っていてどちらに立つべきか注意して観察してそれで全然わからなかった足下を見ても左右に視線をやってレジまわりのポップを眺めても判別できなかったあとになって判明した理由は2つ1つはどこに「現金が使えますとは書かれていなかった「現金が使えないことを知りたいんじゃないんだよしかもそれをレジ前で知っても遅いんだよ(これが2つ目の理由)そして現金が使えないレジを見つけることは現金が使えるレジを見つけることを助けはしない現金が使えるかどうかわからないレジが存在しているだけなんだ現金が使えないレジが現に存在しているのだからこれは自然に生じる疑いだと思いますがどうですあたふたする原因が導線の悪さにある例でしたスキャンを全部終わらせたあとで支払い方法の選択肢に現金がなかったんだよね(サポト店員さんがレシトを発行して現金可のレジに読み取らせることになった)レジを区別するという注意コトを不特定の客に要求しているのだからこれはもうどうしようもないドルがあるから越えられない人が出るなくせないならせめて低くする仕組み作りを続けるしかない


20240622() [AtCoder] 今日はユニークビジョンプログラミングコンテ2024 AtCoder Beginner Contest 359があったF 問題まで解けたけどなぜか D 問題が解けない謎の回ではふりかえりACount Takahashi普通に Takahashi を探したけど制約を読めば T を数えるだけでも良かったらしい他の人の提出で知ったそうか手の抜き方を見習わないといけないな無駄にコンピングパワーを使ってしまったBCouples正規表現の先読みでやったけど結構複雑で罠もあるパターンになったので(/\b(\d+)(?= \d+ \1\b)/)普通に Array.each_cons(3).count{...} でやるのが良かったCTile Distance 2数え方が ABC353-F Tile Distance と同じ斜めを数えてから縦と横を数える横移動のコト計算が難しかった目的地がタイルの右側か左側か判別してから右と左のどちらから移動してくるのか場合分けをしたDAvoid K PalindromeABCDEF で一番難しかったっとねまず否定で良い文字列を定義するのをやめてほしい(わがまま)かなり長いあいだ勘違いしていた何を数えたらいいのかまだわかっていない長さ K の枠の中について回文があるとかないとかを数えるとするじゃないでも枠の外を数えることができない重複を省いてどうやって数えられるのEWater Tank特別なデータ構造はいらないスタックが1つと数を1つ覚えておくだけで答えが出せるこういう単純な道具をこねこねする問題は好きだけど前回の D 問題が灰 diffったことを考えるとdiff どころか茶 diff があるかどうかもわからないと思う高めに出てもそれは D 問題の壁があったからだよFTree Degree OptimizationRuby での他の人の提出を見ると自分のよりずいぶんとシンプルで自分には見えていない何かがあるのかなと思わされる自分が考えたこと各頂点が単独でばらばらに存在していて(相手のいない)辺を1本伸ばしているトはその頂点の値(A)と現在の次数による木を作るのだからN-12本の辺を選んで繋ぐことを繰り返す。繋いだときにコトが発生してそれぞれの頂点からはまた新しい辺を生やす。辺を選ぶのにプライオリーを使ったけど同じ連結成分から生える2本の辺を繋ぐことはできないので単純にキーから2つ取り出して繋ぐというわけにはいかない自分はキーを2本使った1本目のキーにすべての辺を入れて2本目のキーには最小コトの辺とそれと同じ連結成分の辺を入れたそうすると2本のキーの最小同士を連結することでうまく処理が進むだけど他の人の提出を見るとーは1本で足りるみたいなんだよねどう考えるとそうできるのかわからないF 問題次数の和が 2(N-1) になることを利用するのかなーには常に N 個の数を入れておいて2つ取り出してコトを計算して2つ戻す。自分の提出が無駄に複雑になったのは個々の頂点の繋ぎ方を区別していたからだ次数だけをカウトして繋ぎ方は考えないでおくとシンプルになるたぶんねほらね。提出 #54856675 (AC / 753 Byte / 562 ms)ほらねじゃない2つ取り出すのは嘘だった1つずつ N-2 回取り出す。次数の和が 2(N-1) になるというだけでは条件が足りない気がした各頂点の次数が最低でも1あるというのも条件なのかなだから次数 N は予約済みとして残りの N-2 をキーから引いたF 問題tinsep19 さんのこの提出 #54855773 は個々の辺の繋ぎ方を考えつつもシンプル木の問題の制約で自分が好きな形式があってこういう形で親を定めるもの p2,p3,p4,...,pN (1pi<i)これでどんな形の木も作れるんだよこれと同じ考え方で処理を進めていてシンプルになっている自分の考えが1つも2つも足りないのが明らかになっていくなあF 問題自分の最初の AC 提出には嘘があると思う辺を繋いで新しい辺をキーに追加するときに2つ目のキーが空かどうかを確かめて適切なキーに追加するようにしないと取り出し済みのコト最小の辺と2本目のキーに入っている同じ連結成分の2番目以降の辺のトの大小が入れ替わってしまうおそれがあるこれは自分がキップを参照するのではなくとりあえず取り出してみた最小値を変数に保存して利用しているせいで生じているバグあぶないところだったなあGSum of Tree Distance全方位木 DP だと思ったら普通の木 DPったDPDP の中でもやりやすい印象を持っている積み上げの基礎となる葉の部分が最も単純でとっかかりとして好都合だからだと思うその代わり子のマージに神経と時間を使う。提出 #54881518 (TLE×2 / AC×50)2ケースダメでした何が弱点だろうメモリ消費と時間がだいたい比例しているメモリ消費は Hash かなと思うけどどういう形の木だと無駄が増えるんだろう単純に頂点数じゃあないんだよな■精進D 問題XABC305-G Banned Substrings の簡易版だと読んだので自分の提出 #42262239 をなんとか解読してそれっぽいものを書いた。提出 #54884526 (AC / 496 Byte / 147 ms)おもしろいのはっていうかやられたなって思うのは入力文字列中の ? の出番がごく控えめなこと力技で長さ N の良い文字列を構築していくにあたって入力文字列中の AB はふるいとしての役割を果たしているのだけど、? というのは A でも B でもいいという意味だからふるいとして働かないことが機能なのだ注目する部分が間違っていたしプログラムの構成も全く予想していないものだったG 問題トイレでひらめいてしまったージテクのためにサイズでソトしてるんだけどそのサイズって5とか3の固定だったりしませんってからデバッグする。提出 #54896069 (AC / 839 Byte / 3169 ms)通りましたまさかのマージテク失敗が TLE の原因だったあれこれ考えることが多いと手癖にまかせて .sort_by(&:size) とか書いちゃうんだなところで今確認したところ tinsep19 さんが G 問題を 528 ms で通している同じ Ruby なのに桁が違うんだけど何をどうやっているのか知りたいが読んで知りたくはないんだなF 問題「自分の最初の AC 提出 #54840376 には嘘があると思うと書いた実際に確認したところ新しい辺を無条件に2番目のキーに入れていたので懸念していたコトの逆転は起こらないはずだけど代わり「2つ目のキーが空かどうかを確かめて適切なキーに追加することができていなかったことが明らかになったこれの何がまずい新しい辺を空っぽの2番目のキーに追加するとそのキーから選ばれた辺が次に繋ぐ辺の一方として必ず使われるんだけどこれがコト最小であるとは保証されない1番目のキーから取り出されたものを2番目のキーに入れるからコト最小が保証される一方でこれが WA の原因にならない理由もわかってきたどれか1つ任意の連結成分を選んでこれに属する辺を2番目のキーに入れると決めることでも N-1 回の操作で木を構成することができる自分は UnionFind を使っていながらミスによって UnionFind による連結成分の管理を必要としない木の構成法を実行していたなんだかなあ考えが2つ足りず(次数への着目インクリメンタルな木の構成法)実装ミスをし(追加するキーの選定)ミスしたと勘違いをしていた(IMKK)素直に F 問題の AC を喜ばせてはくれないの