/ 最近 .rdf 追記 設定 本棚

脳log[2023-08]



2023年08月02日 (水) [AtCoder] 精進。ARC010-C「積み上げパズル」(黄 diff)。色ボーナスもコンボボーナスも全色ボーナスもマイナスになりうるのがゲームのルールとして直感に反する。でも DP をするならそこは問題にならない。DP 配列を埋める初期値にだけ注意したらあとの遷移では比較して大きい方をとるだけ。どういう DP をするか。コンボボーナスを加算するために最後に積んだ色が何色かで M 通りに分類する。全色ボーナスを加算するためにこれまでにどの色を使ったかを 2^M 通りのビットフラグで分類する。M の上限が 10 なので組み合わせた状態数が最大で 10240 通りになる。遷移の回数 N が 5000 以下だからおおよそ 5000 万の処理量は Ruby には厳しいかと思ったけど、テストケースが制約の上限を攻めていないのか処理時間には余裕があった。定数倍2分の1のために必ず立っている1ビットを効率的に省略する方法を考えていたけど必要なかった。■WA×41WA×18WA×3 のち AC。■41→18 で解消したバグは、色ボーナスとして加算する値が落ちてきたブロックではなくすでに積まれている一番上のブロックの色によって決まっていたうっかりミス(21 行目)。■18→3 で解消したバグは、ブロックが1つも積まれていない状態(スコア0)が存在していなかったこと。■3→AC で解消したバグは、それまではちゃんと対策できていたのに他のバグを解消したときに不要になった気がして省略した処理がやっぱり必要だったために生じた新しいバグで、最初のブロックの扱いをどうするかに関わること。色数 M が1より大きいなら特別扱いは必要なくて、他の色の空の状態(スコア0)から遷移してくることでコンボボーナスなしの色ボーナスだけを加算することができる。しかし使われている色が1色だけのときに特別扱いなしでは最初のブロック(コンボボーナスなしの色ボーナスだけ)がうまく扱えていなかった。M+1 色目が追加できたらややこしいことは何もなかったけど、TLE が怖くて1ビットだって削りたかったときにそれは取れない選択肢。


2023年08月05日 (土) [AtCoder] 今日は第四回日本最強プログラマー学生選手権-予選-(AtCoder Beginner Contest 313)があった。オンサイトコンテストの予選だから問題の難化が予想されたけど、配点でもそれが裏付けられている。100-300-400-550-600-625-625-650 は A-C-D-E-F-Ex-Ex-Ex ってことですかそうですか。今日は 100 分5問の、普段よりビギナー向けのコンテストになりそうですね。以下 ABCE のふりかえりと D の精進。■A 問題「To Be Saikyo」。やることは簡単だけど制約とサンプルがいやらしいですね。ひっかかりません(N=1 のケース)。■B 問題「Who is Saikyo?」。愚直に再帰的に何人に勝っているか数えても許されると思ったけど TLE を出した。「全ての情報が正しくなるように、全ての相異なる 2 人組にどちらが強いかを割り当てる方法が少なくとも 1 通り存在する」という制約から推移律を破るような循環する入力は与えられないと思ったけど勘違いだろうか。あるいは単純に計算量が見積もれていないだけだろうか。N≦50 だから4乗でも通るはずだけど。TLE の原因がわからない。Ruby で最初に提出された #44259309 (kuma_rb さん) の着眼点がすごい。負けなかった人が一人だけいたならその人が最強だと。トーナメントではそういう話を聞いたことがあるけどね(「優勝者とは唯一負けなかった者のことである」)。■C 問題「Approximate Equalization 2」。これは B 問題より簡単だった。平均として考えられる2つの整数(切り捨てと切り上げ)を考えて、A 数列のすべての要素について下げるなら下げる量、上げるなら上げる量を数える。下げる量と上げる量の大きい方が答え。上げるのと下げるののうち操作回数が余った方は2つの平均値のあいだを移動するのに使われている。■D 問題は答えを求める手順がわからなくて飛ばした。もし答えが絶対にわからないときの答え方が用意されていたら、まんまと「わかりません」と答えて WA をもらっていたところだった。■E 問題「Duplicate」。そもそも長さ1に収束するというのがけっこうなレアケース。S="22" でも永遠に短くならない。先頭の文字はどうでもいい。2番目以降の文字が操作後の長さを決める。1なら現状維持(ということは操作により末尾の1文字分減る)。2以上なら伸びる。しかし2から9までの数が2から9までの数を増やして伸びることはない(そうしたら収束しない)。2から9までの数が末尾に至って消滅するまでに何個の1を生成するかを数える問題。右側にある文字数と同じ回数だけ、決まった長さ(1から8)だけ伸びる。右側にある文字数が知りたいので末尾から(ほとんど1の)長さであり操作回数を数える。■D 問題「Odd or Even」。コンテスト終了まで考えていた F 問題 Flip Machines が解けなかったので終了後に D 問題に戻ってきた。N 回のクエリで数列全体の偶奇(の連鎖)が決まるのはわかる。たとえば A[1..K] の偶奇がわかって A[1..K-1,K+1] の偶奇がわかると A[K] を基準にして A[K+1] の偶奇が同じか異なっているか決めることができる。同様にして A[K+2] 以降も決める。A[1] から A[K-1] の偶奇についてもうまいことやって決める。ここからが問題だった。クエリ回数は上限の N 回まで使い切っている。A[K] の偶奇を基準にして同じか異なっているかはすべて判明しているが、A[K] の偶奇を決めることができるのかどうか。たぶんここで K が奇数だということが効いてくるのかな。最初のクエリを思い出そう。A[1..K] の偶奇がわかっている。そして A[K] を基準にした仮の偶奇について、1から K までの範囲の偶奇はどうなっているだろうか。一致しているだろうか異なっているだろうか。もう解けた。■コンテスト成績証自分のすべての提出。D 問題も時間内に解きたかったけど、終了後に1時間かけているので惜しいところはなかった。それというのも人間ジャッジがときどきレスポンスの偶奇を間違えるからなのですね。解答のデバッグと並行していつの間にかジャッジのデバッグをさせられていたのでは時間もかかる。D 抜きでも青パフォが出たのは E 問題様様です。■F 問題について。N≦40 と制約はかなり控えめ。各マシンについてありうる未来はかなり限定されていると思った。操作しなければ2枚のカードについて {表表}。1回の操作で {表裏,裏表}、2回の操作で {表表,裏裏}、3回の操作で {表裏,裏表} これは1回の操作と同じ未来。それでどうする?


2023年08月07日 (月) [AtCoder][Ruby] 「AtCoderの新ジャッジ、Rubyの一部提出がメチャ遅い実行時間になっているのだけど require 'prime' があると遅くなるみたいだなー」 これを見てコードテストで require 'prime' とだけ実行してみたら 2525 ms かかって「マジかー」となったのだけど、その後は 55 ms 程度で落ち着いている。インタープリタ起動のオーバーヘッドがおよそ 40数 ms なので、require 'prime' にかけている時間は 10 ms 程度。まあ妥当。他にも require 'openssl' が数百 ms かかったのも確認したんだけど、次に確認したときは 55 ms になっていた。その次は 80 ms。require ひとつのために確率的に TLE になってペナルティを食らうのは嫌すぎる。■magurofly さんの全く同一ソースの2つの提出がこちら。#44334461 (1897 ms)、#44345492 (66 ms)。一度も呼び出されていないメソッドはコンパイルされないだろうから JIT ではないよね。じゃあ rubygems なのかと思うけど、require 'prime' にネットワークが関わる要素はないよね。ね? じゃあどこで? あるいはジャッジサーバーが?


2023年08月08日 (火) 悪名高きスワイプ広告を解析する - Qiita」■スワイプ広告というものは知らなかったけど、興味深い分析だった。で、Flash 広告を思い出した。あれはフォーカス(黄色い枠だった?)を得るとすべてのキー入力を呑み込むために Web ページの閲覧を阻害する異物であり嫌っていた。スワイプ広告も埋め込みスクリプトによる治外法権が認められている異物らしかった。再実装されたスワイプ処理がお粗末なのか悪辣なのか外からは何とも言えないけど、治外法権を認めていることがそもそも失策であり現状は予期された帰結だと思う。つくづく癌だよな。■■■思い込みで書いてる部分があった。スクリプトを誰が書いているかという部分。自分は広告の配信者だと思ったが掲載者であるかもしれず、元の記事では「あくまで推測だが、おそらくこの誤タップ広告システムでサービスを提供している会社が存在し、」と第三の存在が推測されている。


2023年08月09日 (水) [AtCoder] 精進1。ABC127-F「Absolute Minima」(黄 diff)。サンプルの1を読めば f(x) を1回2回置き換えたときの答えの求め方がわかる。あとは3回4回のケースが想像できればいい。■提出 #44387658 (AC / 1233 Byte / 858 ms)。f(x) を更新するにあたり b は総和を覚えるだけでいい。a については中央値と中央値からの離れ具合の総和が知りたい。それは a のソート列と累積和があればわかる。おなじみ BIT で効率的に動的に管理する。■■■精進2。ABC130-F「Minimum Bounding Box」(黄 diff)。まず入力を絞る。d={R,L,U,D} それぞれについて X 座標の最大値最小値、Y 座標の最大値最小値にしか用がない。X 座標について考える。X 座標の最大値最小値の差が減るか一定か増えるかが切り替わるかもしれない時刻が4つだけある。右に移動する X 座標の最大値が左に移動する X 座標の最大値と交差するときが1つ。右に移動する X 座標の最大値が上下に移動する点の X 座標の最大値と交差するときが1つ。3つ目と4つ目は同様に左に移動する X 座標の最小値が~。Y 座標も同じく最大4つの時刻で差の増減トレンドが変化する。求めるものは差と差の積の最小値だけど、差の増減トレンドと積との関係はどうなっているだろうか。(差が減る)×(差が減る)=(積が減る)、増×増=増、減×増=?、増×減=?。書いててわからなくなった。差が増減する早さに秒速1と2の2種類ある。1種類なら平方数を最大として上に凸のグラフのある範囲を切り取った変化をすると思ったけど、2種類だとどうなるんだろう。下に凸になることがあると思ったから三分探索をしたけど、今になって三分探索ができる単純な形の変化をするとはわからなくなってしまった。■WA×1 のち AC (1480 Byte / 187 ms)。


2023年08月12日 (土) [AtCoder] 今日は ABC314 があった。コンテスト成績証自分のすべての提出。配点を見たら 100-200-300-400-475-475-575-625 だったから E と F は易しめなのかなと思っていたら全然そんなことはなかった。E も F も解けず ABCDG の5完。E は解きたかった。ABCDEG ならこれまででベスト3の順位だった。まだ解けないんだから実のない願望ではある。以下 ABCDG のふりかえり。■A 問題「3.14」。切り捨てを四捨五入だと誤読した。小数点以下 N 桁までしか知らされていないのに四捨五入して小数点以下 N 桁を出力するためにどうしようか考えてしまった。0を補おうか? いま再読すると「小数第 N+1 位で切り捨て」と書かれているのがミスリーディングだと思う(やつあたり)。切り捨てであってもないもの(N+1 桁目)を操作することはできないじゃない。考えちゃうよ。提出 #44490051 (AC / 142 Byte / 43 ms)。■B 問題「Roulette」。制約は小さいしやるだけではある。でもあまりやりたくない気分になる。見通しよく素直に実装すると3パスの操作になる。すぱっときれいに片付ける方法はないものか。考えた結果ソートなんてしてしまう人間(私です)は計算量についてイチからやり直そうな。提出 #44494576 (AC / 235 Byte / 44 ms)。■C 問題「Rotate Colored Subsequence」。色ごとに文字を積んでローテートして取り出すだけではある。でもケチなことを考えた。総要素数が N 個になる M 個の配列を作りたくないなと。要素数 M 個の文字配列だけで済ませたいなと。それで TLE を出しているのはただの間抜け。4-7 行目が良くなかった。提出 #44500699 (AC / 220 Byte / 158 ms)。TLE の解消方法がまだいまいち。reverse_each をやめても前から順に常に上書きするなら同じ結果が得られる。■D 問題「LOWER」。クエリ2と3があると文字列の大文字小文字がすべて決まってしまうのだから、文字列を直接書き換える他に、クエリ2と3の後のクエリ1についてだけ記録を残して上書きすればいい。例によって toupper やら tolower やら locase やらを試してとうとうリファレンスを調べた。upcase の反対は downcase らしいです。提出 #44506770 (AC / 266 Byte / 666 ms)。クエリ先読みが有力だったっぽい。■G 問題「Amulets」。問題の構図は比較的理解しやすく、データ構造の知識が問われる問題だった。持ち込むアミュレットの種類は後出しで選ぶ。どのように選ぶか。n 体目のモンスターまでで総ダメージが sa になるとする。モンスターのタイプ別でも総ダメージを記録しておく。タイプ別総ダメージが大きい方から k 個を選んでアミュレットでダメージを無効化するのが最善。その結果総ダメージが H 未満になるならいいが、H 以上になるなら n 体目のモンスターは倒せなかった。アミュレットの個数と倒せるモンスターの数は比例関係にあるので、アミュレットの数とモンスターの数を増やしながら答えを記録していく。たぶんだけどアミュレットは増加していく単一の集合ではないと思う。つまり、k=2 で選ぶアミュレットは k=1 で選ぶアミュレット+1ではないと思う。だから BIT で都度都度最適な k 個を選ぶようにした。top k の総和を効率良く求めることがこの問題の中心だった。BIT にたどり着く前にはプライオリティキューを貼り付けたりしていた(でも行き止まり)。BIT で個数と総和を管理するのはついこの前 ABC312-F Cans and Openers でやったばかり>提出 #44067838。その問題にその解法は log が余分に付くうまくない解答だったのだけど、それが今日の解答のプロトタイプになったのだから怪我の功名。提出 #44529976 (AC / 1412 Byte / 1731 ms)。べつに今回が2回目ってわけでもない。ABC287-G Balance Update Query への提出 #38427641 でもやってる。


2023年08月14日 (月) [AtCoder] 精進1。昨日あった AGC064(不参加)-A「i i's」。最初は昇って降りる階段を作ればいいのかと思った。1234444332 みたいなのを。WA です。問題をよく読んでほしいんだけど、隣接項の差の絶対値は1か2でなければいけない。ゼロではいけない。せっかくなのでこの階段からスワップを繰り返して答えが作れないかと考えてみたがうまくできなかった。ステップ1。N=5 だとして 545454545 みたいにして5と4のノルマを消費したい。ステップ2。同じようにして 32323 を使って2と3のノルマを消費したいが、54...45 の隣に並べてしまうのは良くない。2個までなら並べられるけど、3回以上並べると第 L 項と第1項の差が4、6、8……と拡大し続けてしまう。5と4のあいだに埋め込むのが正解。1になるまで再帰的に埋め込みます。提出 #44571247 (AC / 461 Byte / 125 ms)。あ、また忘れてた。隣接2項の差がゼロではいけないから、両端が5ではいけないから、1回だけ横に並べたあとで再帰的に埋め込みをします。N が3以上なので必ず1度は横に並べられます。■■■精進2。同じ AGC064-B「Red and Blue Spanning Tree」。初手はひらめきです(初手でひらめいたということではなく、有効な初手をひらめくまであれこれ考えたという意味)。辺を3種類に分類した。すなわち、両端の頂点の色と辺の色が一致している辺、片方だけが一致している辺、両方ともが異なっている辺の3種類。両端が一致している辺はどんどん無条件に使用して良さそうな雰囲気がある。それから。大きさが2以上の連結成分に属する頂点についてはすでに条件を満足している。いまだ孤立している頂点をなんとかしたい。端点の片方だけ色が一致している辺を使ってなんとかしたい。その結果孤立頂点がなくなったなら、あとは使える辺をすべて使って全域木を構成する。もし孤立頂点が残ってしまったなら、答えは No。■WA×33WA×8WA×2WA×21 のち AC。ステップ2で孤立頂点を解消する手順がずっとバグっていた。孤立頂点からすでに充足している大きな連結成分へと優先して辺を引っぱらなければいけなかった。まかり間違っても孤立頂点と孤立頂点を片方だけしか満足させられない辺で結んではいけない。■いやね、その場合でも孤立→孤立→大きな連結成分みたいにして最後に大きな連結成分に行き着くのなら問題がない。でも行き着かないケースもある。それが WA×2 の原因となった cycle と名のつくケースだと思う。手元で作った最小ケースはこんなの 4 4/1 2 R/4 3 B/4 1 B/3 4 R/RRRB。1と2の頂点は1番の辺で両方とも満足している。3番の頂点を満足させられるのは4番の辺だけ。4番の頂点を満足させられるのは2番と3番の辺だけど、2番の辺を使ってしまうと3番の頂点を満足させる方法がなくなってしまう。2番の辺と4番の辺は同じ2頂点を結んでいてそれぞれ異なる側を満足させる対称的な辺だけど、これに正しい優先順位を付けて使用しなければ答えを誤る。


2023年08月15日 (火) [AtCoder] 精進。ABC140-F「Many Slimes」(黄 diff)。問題はシンプルに見える。自身未満の体力のスライムしか生み出せないのだからできるだけ大きい体力のスライムからスタートして、できるだけ大きい体力のスライムを生み出すのが最善。■提出 #44614623 (WA×22)。S をソートして前から 2^k 個の要素が次の 2^k 個の要素より大きいことを k=0..N-1 について確認すればいいかと思ったが違った。多少の融通がきくようだ。■提出 #44621584 (AC / 1076 Byte / 1108 ms)。待ち行列を2本持つことでプライオリティキューを使わないでもいいかなとか考えてダメで、プライオリティキューでやろうとしてダメで、BIT でやった。難しい問題ではなかったはずだが回り道が多かった。■もっと短くてオーダーの優れた賢い解法があるらしい。たぶん最初に最大の要素に N 個の要素を生み出させて、その次の世代に N-1 個の要素を生み出させてとやるのかなと思ったけど、これも単純に前から貪欲にやるわけにはいかないみたい。たとえば最大の要素にはできるだけ大きな要素を生み出してほしいけど、N 番目に生み出された要素が次の世代を生み出すことはないので。


2023年08月16日 (水) [AtCoder] 提出結果ページのソースコードが見られない。「SyntaxError: invalid identity escape in regular expression editor.bundle.min.js:1:882506」というエラーが出るのはブラウザが古すぎるせいかもしれないけど、ページのつくりとして、静的に完成したページを出してからデコレートしてほしい。そしたらデコレート部分がシンタックスエラーで壊れていても影響がない。提出結果ページにおいて不可欠のコンテンツが提出内容であるソースコードだということを忘れてほしくない。そして、コンテンツはマークアップ対象としてあるべきであって、属性値に置くのは筋違いだというのが原理主義的な意見。スクリプトがなくても、スタイルシートがなくても、タグがなくても残るのがコンテンツ。もっとも、最近そういうのは API をたたいて JSON なりなんなりで取得するみたい?■Twitter でも提出結果ページが壊れてるって報告が見えるので流動的だとは思うけど、とりあえずこれで>AtCoder-Submission-Page-Fix.txt。以前の提出結果ページとくらべて copy ボタンは機能しないし行番号もなくなったけど、それでも、最低限はある。ソースコードが読めるようにはなった。


2023年08月17日 (木) [AtCoder] 精進1。ABC149-F「Surrounded Nodes」(黄 diff)。前前前回の ABC312-G「Avoid Straight Line」(20230729) を思い出させる問題だった。今日の問題のキーワードは「主客転倒」と「余事象」。ひとつひとつの頂点が穴だと数えられる場合の数を数えて最後にその和を全体で割った。提出 #44647884 (AC / 337 Byte / 588 ms)。■精進2。ABC136-F「Enclosed Points」(黄 diff)。シンプルな問題。これもキーワードは「主客転倒」と「余事象」、それと「包除原理」だろうか。ひとつひとつの点について f の値に寄与する集合 T の数を数えたい。裏返して、寄与しない T の数を数える。それは、T が左(、上、右、下)にある点だけからなる場合。T が左上(、右上、右下、左下)にある点だけからなる場合を重複して数えないようにする。左上にある点の数を数えるのに BIT を使った。提出 #44669970 (AC / 687 Byte / 1095 ms)。


2023年08月19日 (土) [AtCoder] 今日はキーエンスプログラミングコンテスト2023夏(AtCoder Beginner Contest 315)があった。コンテスト成績表自分のすべての提出。以下 ABCDE のふりかえりと F の精進について。■A 問題「tcdr」。String#tr にはあまり自明ではないふるまいがあって、展開後の第2引数が第1引数より短い場合、第2引数の最後の文字が足りない分だけ補われる。最後の文字が存在しない場合(第2引数が空文字列の場合)は第1引数を削除する処理になる。他の人の提出で今日初めて知ったのだけど、String#delete という、まさに tr の第2引数が空だった場合に相当する処理を行うメソッドが存在していた。それも Ruby-1.8 のときにはもう存在していた。知らなんだ。■B 問題「The Middle Day」。制約が小さいので愚直にやる。だけどあまりに無駄な愚直をやってしまった。"月 日" という文字列の配列を全部生成してから真ん中を選んだんだけど、そこはさ、単に通年での day-of-year を数えておいて、文字列を生成するかわりに適切なタイミングで答えを出力すれば良かったじゃない。■C 問題「Flavors」。フレイバーごとにおいしさを記録してから異種組み合わせと同種組み合わせを考えた。ツイッターを見てると最大のおいしさが必ず採用されることに着目した解法が目立つ。そのアイスを2回食べてしまうミスにだけ注意すれば配列1本で処理できるのが魅力的な解法だと思う。ミスへの対処法は、必ず選ぶ1つを配列の先頭もしくは末尾の要素とスワップして、先頭もしくは末尾を探索範囲から外すのがいいかな。■D 問題「Magical Cookies」。最終的に E 問題の3分の1くらいしか正解者がいないいわくありげな問題。下手をするとすぐ TLE になるみたい? 自分も 35 分と、E 問題より時間をかけて慎重にやっている。TLE 以外に小さな罠もあるにはあって、問題文に書いてある通りの手順を守らないと最後に残るクッキーが違ってくるような気がする。行を取り除くには2列以上、列を取り除くには2行以上残っていないといけないという条件から、残り2行もしくは残り2列付近で手順が最終結果を左右するのではないかと思う。手順を守るように途中で書き直したおかげかは知らないけど、というか書き直しだけなら5回も6回もそれ以上でも行きつ戻りつしていたのだけど、ペナルティを出さずに AC だった。TLE を回避する手段は、まだ残っている行番号と列番号を記録して使用することと、行と列にある文字の種類と数を記録して使用すること。■E 問題「Prerequisites」。スタックに積んで順番に読むだけ。WA を出したのはひとえにあほだからです。もう読んだフラグを立てるタイミングを間違えた。そのタイミングで何かするのを帰りがけ順っていうらしい(聞いたことはあるよ)。■F 問題「Shortcuts」。とりあえず DP で解けるのはわかる。制約が1万以下とよくあるものより1桁少ない。2乗で1億、定数倍2分の1で 5000 万。言語アップデートにより「倍早い」こともある Ruby-3.2 ならワンチャンあるかという数字。時間内に提出したものは TLE だった。ああ無情。■F 問題。悪いのはもちろん Ruby ではない。実は途中で必要に迫られて DP 配列の次元を増やしていた。O(N^3) にはどんなチャンスもない。ツイッターで見ちゃったんですよ、ペナルティは 50 回まで考えれば十分だと。見積もってみれば 28 ビットで上限を突破しそうだったので 30 を上限にしてみたら通った。O(30*30*N) だから 900 万のレベル。大枠は完成していたんだから時間内に通したかったねえ。


2023年08月21日 (月) プラグが折れてコンセント内に残った! 怖過ぎる1枚が話題に、こんなときどうすればよいのか東京電力に聞いた(1/2 ページ) - ねとらぼ」■小学校の低学年くらいの頃、ふとした衝動から自転車の鍵をつっこんだことがある。手に鍵があり、目の前に穴があったのだ。ヴヴヴヴと震えるような感触があってあわてて引っこ抜いたのでした。感電とは違うのではないかな。しらんけど。


2023年08月22日 (火) [AtCoder] 精進1。ABC133-F「Colorful Tree」(黄 diff)。高速に木を処理する問題。2つの頂点のあいだで、距離と、指定した色の辺の数と、指定した色の辺の長さの和が知りたい。距離は根からの距離を調べておけば LCA を引き算して求まる。色の辺についても同じことができるけど、色の種類数が最大で N-1 あることが問題になる。予めすべての色について調べて記録しておくことは N^2 になるのでできない。どうするか。クエリ先読みでやった。■提出 #44828105 (AC / 1276 Byte / 1269 ms)。木でクエリ先読みというと ABC202-F「Count Descendants」を思い出す。コンテスト中に解けたのは会心の出来だったから。■■■精進2。ABC143-F「Distinct Numbers」(黄 diff)。K 枚のグループがいくつ作れるかを二分探索した。グループ数を G とする。G 枚より多いカードは G 枚だけ使える。それ以下の枚数のカードは全部使える。使える枚数が K×G より少ないかどうかで判定する。■提出 #44829467 (AC / 247 Byte / 932 ms)。あーっ、今なら ABC の D 問題に Project Planning (青 diff) が出てきても解けるなあ。同じ問題だこれ。■提出 #44843265 (AC / 190 Byte / 336 ms)。まったく同じではない点は、この問題の K は 1 から N まで可変だということで、サンプルを見てわかるように K が増えるにつれ答えである G は減少するという性質があるわけで、個々の K について独立に二分探索で答えを求めることには無駄があった。


2023年08月23日 (水) おしっこ(真面目な話)」■この話題は、なんでダメだ我慢しろという意見が主流になるのかわからない。出せばいいよ。別に汚くはないし、汚いというなら体の表面からはがれ落ちるものも同じくらいに汚いよ。お風呂はそういう場所でしょ。どちらかというと液体の方が面倒がないよ。もちろん他人がいないという前提での話。人前ではふるまいを考えよう。■増田は条件付けされると似た条件の他所でも漏らすからやばいと感じている。でもお風呂で感じる尿意は条件反射というよりは排尿反射の一部なのではないかと疑ってる。一度出始めたおしっこが途中で止められないように、水(お湯)による尿道への物理的刺激が尿意を誘発しているのではないかと。尿道炎になりかねない(と警告されそうな)のでおすすめしないけど、シャワーの水を注ぎ込んでみればトイレに行った直後でも尿意を引き出すことができる。■規則正しい生活をしていれば毎日寝る前の決まった時刻にトイレに行くことができる。そうしたら寝てるあいだには漏らさないよ。増田は自分で書いているように、自律神経がおかしくなっていたのが主因だったと思うな。■増田の趣旨からは外れるけど、お風呂→おしっこの条件が成立することは、お風呂入ろうかな→おしっこしたいな→先に出しておこうという行動につながるのでいい条件だと思う。■規則の話。自分は起きているあいだはほぼ3時間で1回分のおしっこがチャージされる。だから8時11時14時17時20時(寝る直前までちょっと我慢して)25時の1日6回が基本サイクル。どうでもいい話でしたね。


2023年08月24日 (木) [AtCoder] 精進。ABC158-F「Removing Robots」(黄 diff)。この問題が黄色になってるのは、前に置かれていた E 問題の diff がやや下の青色だからという理由が大きいと思う。普通に一直線の DP だった。■提出 #44882536 (AC / 216 Byte / 408 ms)。ロボットを X でソートして順番に場合の数(起動した場合1 + 起動しなかった場合1 = 2)を記録する。そのとき、移動範囲内にあるロボットの場合の数を、起動した場合の数に併合しておく(掛け算)。最後に残るのは連結成分ごとの場合の数なので、掛けて答え。■えっと、併合するのは起動しなかった場合であって、常に1だけ加算して記録するのが起動した場合の数なのでは? どちらの初期値も1だから答えは合うけども、試行錯誤しているうちに理解がねじれていた。


2023年08月25日 (金) [AtCoder] 「提出結果ページのソースコードが見られない」のつづき。Ace という名前の何かを提出結果ページと提出ページに採用したらしく、機能性を追加しつつ以前のようにコピーボタンや縦スクロールバーのオンオフや行番号表示が機能している。ま、提出ページでは貼り付け&送信しかすることはないけども。コピーボタンは AtCoder 謹製なのかな。必要にして十分ですよ。自分の提出をアップデートしたいときにちょいちょい使ってる。でも今回エディタ部分があまりにきっちりできあがってるので、Ctrl+(A、C) で全選択&コピーもできる。■カーソル行強調と対括弧強調がうるさいので消したのだけど、すごく頭の良さそうな(←語彙力)つくりになっていた。ソースコード領域は複数のレイヤーが重ねられていて、テキストレイヤー、マーカーレイヤー、カーソルレイヤーが主だったところ。マーカーレイヤーを非表示にしたらうるさい強調は全部消える。でも範囲選択も消えたので個別に消した。■インデントレベルを示す薄灰色の縦線が目障りだなと思ってこれも消そうとして気がついたんだけど、折りたたみ機能があるんね。でも Ruby の場合、縦線で結ばれていても折りたたみできないことがある。この提出(#38427641)の 17 行目の左シフト << をおそらくヒアドキュメントの開始と勘違いしているせいで、lb メソッドと BIT クラスが折りたたみできなくなっている。直前に数値(1)があることは認識できてるんだから、ビットシフトと解釈するのが自然だと思うんだけどな。数値と文字列をそのまま並べるような文法はないのだから。■インスタンス変数 @aace_variable ace_instance とクラス分けしているあたり、完璧ではないけど Ruby のことを知ってそうな雰囲気はある。■レイヤー分けの弱点がこういうところに現れたのだろうか。「AtCoder の新エディタに使われている Ace、多バイト文字の扱いがたまに怪しいので、 「※」などの全角記号を使うとカーソルの位置がズレる (※は「なでしこ」の行コメントの1つ、「プロデル」のプリプロセッサとして使われている) https://t.co/YwDlWqNNjf」。ひらがなとか漢字を使ったくらいでは問題ないので、あまり気にすることはないかな。それを確かめるためにさっきリンクした(日本語変数を使っている)提出をいろいろ調べていた。■もう昨日だけどこんなんがあったらしい。「新エディタテストコンテス」。A 問題難しくない? 前回の ABC-G に似た雰囲気を感じる。


2023年08月29日 (火) 犬と散歩するときはルールを守りましょう→この写真がなぜか一万いいねされる「通知欄がスーパー肛門フェスティバルの会場と化してしまったので通知を切ります」 - Togetter」■マナーがルールによって上書き訂正されている看板。いろいろな受け止めができると思う。それはつまり効果的な看板ではないということ。まず文言。マナーがルールになったことで「ルールを守るのは当たり前のことやん、当たり前のことにわざわざ『犬と散歩をするときは』と条件を付けるということは、それ以外ではルールを守らんでいいということか」と勘ぐる余地を生み出してしまっている。ルールではなくマナーだったらぎりぎり不自然ではないかなと思う。■次が本題。この看板が何を訴えているのか、それがわからなくなった。マナーであれば、犬のうんこは持って帰ろうねとか、リードは必ず使いましょうってことかなと想像するけど、ルールとは何か。どこにどういう内容が定められているのか、自分は知らない。ルールを守ろうね、では当たり前すぎて何も伝えていないし、~が決まりですと書くのが効果的だと思う。ルールは知っていて当然(だからあえてここでは書かない)という態度は嫌いだな。もし決まりがないんだったらそれこそ意味不明な看板だけど、実際のところどうなんだろう。もともとマナーに訴えていたんだからなかったと思うんだけど。あるいは飼い主なら当然知っておくべき犬の散歩に適用されるグローバルなルールがありますか。


2023年08月30日 (水) 株式会社キョウプロ」 毎週末コンテストを開いているとかいないとか。


2023年08月31日 (木) [AtCoder] 精進。ABC191-F「GCD or MIN」(黄 diff)。最初のとっかかりとしてまず gcd を無視して min を考えた。min だけのとき最後に残るのは A 数列の中の最小値。ここに gcd がどう関わってくるか。gcd(a,b) は必ず min(a,b) 以下の数になる。そして最小値は最後まで残すことができる。まとめると……。A 数列の最小値を M とする。M は最後まで残すことができる数のひとつであり、その中では最大のもの。gcd(A[a], A[b], A[c],...) によって作ることができる M 以下の数はすべて最後まで残すことができる。その種類数が答え。■提出 #45084618 (AC / 725 Byte / 1974 ms / 5332 KB)。DP をした。それも頭の良くない DP を。まず A[0] を配列の先頭に配置し、以降 A[1] から A[N-1] について、配列の全要素とのあいだで gcd を計算してそれら gcd と A[i] そのものを配列に追加した。重複がないとすると伸びていく配列のサイズは 0,1,3,7,15,...,2^N-1 という感じで成長していって、N≦2000 だから2の 2000 乗はやばいんだけど、実際は gcd が1になったり重複したりすることが多いのでそれなりに大丈夫。でも Ruby では4から5秒かかって大丈夫ではなかったので C++ の犯罪力に頼りました。実は C++ であっても2秒を数百 ms オーバーしてしまったので、GCC ではなく Clang を選んだり、set ではなく unordered_set を使ったり、2つ使っていた unordered_set を1つに減らしたり、初期にあまり配列を伸ばさないで済むように A 数列をシャッフルしてみたりした(※逆にソートすると悪化した)。それでも2秒を 50 ms ほどオーバーしてしまったのだけど、unordered_set に大きめの初期サイズを与えると 100 ms 弱縮んでようやく AC の目途が立った。Ruby で通してる人は素因数分解をしたりしてるんだろうか。Ruby でも3桁 ms で AC がとれるらしいんだよね。自分にはわからんけども。■ブログを2つほど読んだ。約数を列挙してそれが GCD になりうるかどうかを調べるといいらしい? さっき書いた素因数分解~云々がそうなんだけど、素因数の指数部分を減らしてみて、共通部分を持つ他の要素を(1つ以上)見つけて、非共通部分の GCD が1になるかどうかで答えの候補になるかどうかがわかる。でも計算量的にそうした方がいいという判断ができなかった。■Ruby で約数を列挙してさっき書いたようにして答えを出してみたら、many_divisors_00.txt というケースが最長で、2秒を 121 ms オーバーした。ましにはなったけどまだ考えが足りないらしい。提出 #45095866 (AC / 628 Byte / 192 ms / 9844 KB)。Ruby では TLE 間違いなしなのでこれも C++ だけど、1974 ms → 192 ms で 10 倍ましにはなってるんだな。このうえさらに Ruby で通すのつらすぎるぜ。■提出 #45096878 (AC / 259 Byte / 1762 ms)。これは Ruby。AC と TLE の分かれ目はまさかの約数列挙ループだった。while b*b<=a; if a%b==0; c = a/b end b+=1 end なら AC で、while b<=c; if a==b*c; end c = a/b+=1 end なら TLE。AC の方では足し算1、掛け算1、剰余演算1が毎回で、約数が見つかったときだけ割り算が1。TLE の方は足し算1、掛け算1、割り算1を毎回やっている。剰余と割り算のコストが同程度なら剰余を求めないで済んでる分得かなと思うんだけど、そういう結果ではない。違うんだ? ループ回数は同じだと思うし、どこで差がついてるのか本当にわからない。■3桁 ms の2つの提出(#20120433, #20414187)を読んだ。約数列挙に工夫があった。最初に素数を列挙している。たしかに1ずつ加算して割り切れるか確かめるより、素数について指数を調べる方が効率が良さそう。