09/19(月)
午後2時起床。先週の週記を少し書きつつ、もっぱらハーメルンを読み続けていた。午後10時前に1作読了。「犬とお姫様」。
先週日曜日、つまり昨日読了した「女王様と犬」の続編で、比企谷八幡が高3、その他雪ノ下雪乃をはじめとする原作組がほぼ一律で高1となっている。雪ノ下陽乃は大1になっているので姉妹の年の差は原作と同じらしい。高1、高2と雪ノ下陽乃に付き従うことで鍛えられた比企谷八幡のスパダリっぷりが良い。年下になった原作ヒロイン組との関係やその中で改めて構成された原作と同じイベントたちが目新しく、非常に面白かった。
午後11時半を目前にして何とか週記の文章を作った。量が少ないのでハーメルンにかまけていても間に合ったのだ。読み返さずにいったん投稿。
CFの準備をしていたらスマホに通知が来た。30分後からTCO Finalsに関するオンラインミーティングがあるらしい。「午前12時から」と書いてあったので火曜日正午のことなんだなあと思っていたのに、実は日付が変わった瞬間だったようだ。心構えだけしてCF #821 div.2に出た。
Dashboard - Codeforces Round #821 (Div. 2) - Codeforces
Aはインデックスをで分類してそれぞれ最大値を取る。Bはとのどちらか一方がで、もう一方がの約数であればよい。Cはちょっと手間取ったが全要素を等しくすることができる。と偶奇が一致するところだけ見て一番後ろの値を全体にコピーし、その後残りにをコピーする。
D1はちょっと面倒。とで異なるインデックスを取り出し、奇数個であればとなる。偶数個なら必ず達成できて、特に4個以上なら2個ずつコストで揃えられるので、これが明らかに最適。問題はちょうど2個のときで、ここを頑張って場合分けした。まず隣接していないならコスト。隣接しているとき、その左または右に2マス以上空きがあったら、そこを経由することでで揃えられるので、必要コストは。
今なので最後の条件は必ず満たされる。コンテスト中はこれに気づかずまだ場合分けを続けた。左右に1マスずつ空きがあった場合はになって、これも満たさなかった場合はどうしてもかかってしまう。
D2はdp。あらかじめの場合をD1によって取り除くことで、先ほど場合分けしたような左右の空きマスを経由する場合を考える必要がなくなる。あとはどのようにペアにして揃えていくか。異なるインデックスだけ取り出したときに隣り合うペアをで揃えるという遷移と、によって揃えるペアの一方として確保する、または以前確保したものとペアにする遷移だけ考えればよい。
確保している個数を次元に持って。実際は2個確保した段階でその二つをペアにしてしまってよいので、でも解ける。今なので、うっかりインデックスとして隣接するペアをで揃える遷移をしても問題ない。
ここまで解いたらちょうど日付が変わったので、オンラインミーティングに参加。その間はEの実験を行っていた。そうやって別のことに意識を取られていると、まず英語が全く聞き取れない。内容は全部チャット欄にまとめられた文章で把握していた。一方でEの考察も全然進まなかった。
ミーティングが終了してから改めて考えるとすぐ解けた。秒後にスライムがあるとしたら、それはもともと秒の時点で追加されたものであり、それより前に追加された個のスライムだけが今注目しているスライムの動きに影響を与える。
ここで、に追加された個のスライムのうち、個が右に、残りが下に進んだとわかることに気づいた。以降同様に各マスにいくつのスライムが到達したかわかるので、これを全体に対して求めた後、個目の動きをシミュレートすればよい。
全完7位。上に4人も日本人がいるのは何事だろうか。
ハーメルンを1作読了。「ようこそ元暗殺者のいる教室へ」。主人公の間延びしたセリフが好きになれなかったが、暗殺教室とよう実のクロスオーバーはいいなと思った。もっといろいろ読みたいと思って探したところ、ほとんど存在しないことが分かって残念。
週記の校閲を済ませて午前4時くらいに布団に入った。30分ほどハーメルンを読んで就寝。
09/20(火)
午前11時起床。
布団に横たわったままハーメルンを1作読了。「RPG要素があるエロゲのRPG部分にドはまりしてエロそっちのけでハクスラするタイプの転生者」。日間ランキング1位だったので読んでみた。なぜ狂人と思われているのかの理由付けが上手い。最新話まで読み進められたくらい面白くはあったが、今の気分とは微妙にずれているように感じて、それほど印象には残っていない。
昼食を摂り、しばらく本を読んでいた。午後5時前になってからノートPCの前に陣取り、インターン先の定例会に備える。月曜日が祝日だったので今日のこの時間にずれていた。
ノートPCにマイクがなくて、チャットによる参加になってしまった。先週の進捗はない。勉強会はOpenCVの話で、様々な画像処理や図形検出の関数が紹介された。幾何の問題として出くわしたら逃亡を選びたくなるほど面倒そうな処理がいくつも実現されていて、その手厚さに感動した。
夕食と入浴を済ませた後、リビングに転がって午後9時から2時間ほど寝てしまった。起きてからSRMに向けた準備をする。Appletを導入するつもりだったが、うっかり寝入ってしまってそれほど時間的な余裕がないので、今日もWeb Arenaで頑張ることにした。午前0時からSRM838。
https://community.topcoder.com/stat?c=round_overview&er=5&rd=19420
Easyはシンプルに実装が遅かった。最初にbitsetでdpして復元することを考えて、さすがに面倒だったので、選んだ要素を直接vectorで保持したままdpできないか考えてみた。定数倍もよくて十分間に合いそうだったので実装。サンプルを合わせてから、本当に間に合うかもう一回見積もりをやり直したり、最大ケースを試すかどうか迷って結局試さなかったりと時間をドブに捨て続け、提出したら200点を切っていた。
Medはバカ発見器で、自分は発見されてしまった側。ダイスの面数を昇順に見る。これまでの期待値をとしたとき、新しい数が出る確率がになるらしいので、と更新する。を前計算すれば十分高速。これに気付くのに30分以上かかってしまった。
後から計算して納得。期待値がと計算されたとする。ここでは種類数であるような場合の数で、はすべての場合の数の和、つまりである。ダイスを面数の昇順に考えているので、今の面数をとしてこれまでの種類数は必ず以下であることを用いると、各について新しい数が出る場合の数は通り、そうでないものは通り。
よって更新後の期待値は。整理するととなり、先ほどの式に一致する。
Hardは辺の長さ昇順に見て、それ以前の辺によって端点が連結になっていない確率を求められればよい。これはABCで数え上げ版の出題がある。その場で再現できなかったので、少し時間を使って以下の問題を探し当てた。しかし数え上げを確率の計算に書き直せず、それっぽいものを書いて試そうとしているうちにコンテストが終了した。
チャレンジフェーズは何もせず。Hardが結構落ちてくれたので少し順位は上がったものの、27位となり、レートは2887→2785(-102)。今日はシンプルに僕が悪い。僕の頭が悪い。Hardはコンテスト中に書いていたものを完成させてみたがサンプルすら合わず。がやたら小さいことに注目し、UFの状態を全通り持つべきだったらしい。
読書に戻り、午前4時半に1冊読了。「虚構推理短編集 岩永琴子の純真」。第一話「雪女のジレンマ」が好み。雪女とその恋人の馴れ初めが延々語られ、推理は最後のアクセントに。その使い方も苛烈ではあったが人を幸せにする方向で、ハッピーエンドで良かった。ただこれだけで表紙にまで雪女が描かれるのはびっくり、と思っていたら第五話も雪女に関する話だったらしい。こちらも優しい終わり方だった。
さらにハーメルンを読んでいたが、午前6時を過ぎたあたりで寝落ちしたらしい。その後いったん目覚め、そのタイミングで就寝報告のツイートをしていた。
09/21(水)
午前10時半起床。午前11時からTA研修会というのに出たが、これは心得を読み上げるだけで10分程度で終わってしまった。
昼食を摂り、荷物を纏めて昼過ぎに実家を出た。仙台に帰る。母に車で駅まで送ってもらい、午後2時半の新幹線に乗った。車内では1時間ほどハーメルンを読み、残りは本を読んでいた。
— こたつがめ (@kotatsugame_t) 2022年9月21日
午後7時帰宅。PCを起動してしばらく触っていたら眠気が強くなってきて、午後8時から午前1時半まで布団で寝ていた。
起きてノクターンノベルズを1作読了。「無愛想な転校生の裏垢を見つけてしまった。」。もうすぐ電子書籍になるようで、TLに流れてきた表紙イラストに興味を持って読み始めた。それなりに話数はあるものの思ったより進展が遅かった。主人公のリアルとSNSアカウントが紐づけられる展開を期待していたが、まだ描かれていない。
https://novel18.syosetu.com/n0085hq/
その後もノクターンノベルズを漁っていくつか読んでいた。朝が近づいてきて、さすがに明日のセミナーの準備をしないとまずい気持ちになるものの、なかなか手が動かず、結局午前8時になるまでずっとTLを見たりYouTubeを眺めたりしていたらしい。そこから1時間だけ前回の発表資料の残りに付け足したりして、午前9時就寝。
09/22(木)
午前11時半起床。二度寝は怖いしかと言って身を起こすほどの元気もなく、布団に横たわったまましばらくスマホを触っていた。正午くらいにやっと起き上がって準備し、出発。山の上の購買に閉店間際に滑り込んで確保したパンやおにぎりを食べ、午後1時からセミナー。
まず自分の発表が3時間弱。頻繁に止まって確認したり例を挙げたりしつつ丁寧にやっていたら、昨日新しく用意した部分まで進まなかった。なかなか伝わらず大変。うまい具体例を用意できなかったのはあるが、説明も悪かったのだろうか。証明を、「お気持ち」がわかりやすくなるようにと教科書のものから少し変えてみたら、必要な性質を正確に導くのがかなり面倒になったので、そこは失敗だったなと思う。感覚的には明らかなので深く考えていなかった。
次に博士課程の方のセミナーが2時間弱。先々週の続き。これまでずっと前提知識の部分で詰まっていたのが、じわじわ進んで今日ついに補題の証明に入り、感動した。肝心の証明は道具を念入りに確認していただけあってスムーズに理解できた。
午後6時帰宅。小一時間TLを眺めた後、思い立ってラノベの新刊チェックをした。一通り調べていざ注文、という段階で眠気に耐えられなくなり、布団へ。午後9時から午前0時半まで寝ていた。起きてからしばらくノクターンノベルズを読んでいた。
PCの前に戻ってリストアップしておいたラノベを注文。9月下旬から10月下旬まで一か月ちょっとの間に出る作品で、今回は28冊とかなり多めだった。新作にはそれほど手を出していないので、追っているシリーズの最新刊の出版時期が被っただけらしい。
午前3時から昼まで日記を書いていた。途中頻繁にYouTubeやハーメルンで集中を切らしてしまうのでそれほど捗らなかった。書いている間に話数が少ないものを2作読了。
「大学生、上杉風太郎。インフルエンサーでホストやってます」。五等分の花嫁は原作をほとんど知らないのに、これは完結後の話だったので、回想の描写から結末に至るまでどういう展開やシーンがあったか薄々想像がついてしまった。まあこれは原作を知らないのに二次創作を読むときの宿命か。内容については良くも悪くも感じていない。ただ、ホストっぽいキャラはよくても主人公がホストそのものというのは好きになれなかった。
「国民的大物女優観察記録」。こちらの原作は全く何も知らなかったので、ほぼオリジナルと変わらない感覚で読んでいた。好感の持てる勘違い主人公で面白かった。エタりかけに見えるが、ちゃんと一段落するところまで投稿されていたのが嬉しい。
午後1時前に就寝。
09/23(金)
午後8時半起床。今日はコンテスト二つ。まず午後9時からCF #822 div.2。
Dashboard - Codeforces Round #822 (Div. 2) - Codeforces
Aはソートして連続する3要素を真ん中に寄せるのを全探索。Bは実験エスパーで各段の両端だけ1にした。Cはに対してその倍数を全部見てどれを消せるかチェックすることで、逆に各値を消せるの最小値が求まる。実際、小さい値から順にいま求めたで消していけば達成できる。今考えてみれば、を昇順に見て消せる値を貪欲に消しても同じことだった。
Dは難しかった。吸収したスライムの区間をとして、の累積和を取ることで必要な条件がと書ける。を固定してを右に動かすことを考えたとき、先の条件を満たせる限界までいったん動かしてみて、その中でが最大となるところを新しいにして損しない。ただし端まで到達できるなら即座にYESとなる。についても同様のことを行い、どちらでもを変化させられなくなったらNOである。
Eも難しい。が交差の等差数列になるように定めると、となる。かつよりこの値はで一致せず、よって条件を満たす。どうやって思いついたか定かではない。確か、行または列の値を揃えて少しずらすことを考えていたのだった。
Fも難しい。難しい問題だらけ。を満たすを取り、がのflipであることを利用することで、いくつかのより小さいに分けて再帰的に求められるが、クエリの個数が爆発してしまいそう。しかしよく観察すると種類数が少なかったため、メモ化することで十分高速になった。トリックはこうだ:分割後にを満たさないものは高々一つであり、さらにが2べきの場合、以降何度分割してもその回数ごとに高々2種類のクエリしか生成しない。
Fに1時間かけて順位が崩壊した。全完19位。
シャワーを浴びて午後11時半からCodechef、September Lunchtime 2022 div.1。3時間半もあって大変。ペナルティがないので提出し放題だったのだが、各問題に60個程度テストケースがあって、提出するたびにいちいち神経をすり減らしながら待つ時間が発生して辛かった。
https://www.codechef.com/LTIME112A
INCADDはを観察するとすぐ解けた。この値をすべて非負にしたい。区間更新はある範囲にしたあと右端を大きくマイナスする操作になるので、常にとして操作することでそのマイナスを無視するのが明らかに得。さらにとすることで全体にすることにして、回操作すればすべて非負にできることが分かった。セグ木で管理しての更新に対応。ただし操作回数も当然非負である必要があり、これはセグ木に乗せるモノイドの単位元をにするだけでは不十分だった。all_prod
の際わざわざ単位元を掛けたりしていないのは当たり前。
ADJACNTPAIRSは簡単。最終状態を決めたとき、それと異なる値を一つ一つ揃えなければいけないのに加え、ちょうど一つずれたような連続部分列があればその長さに対してだけ余分に操作しなければならない。これは高々種類しかないのであらかじめ計算しておく。あとは最終状態の偶数番目と奇数番目としてそれぞれにおける出現回数が多い順に値を試していく。通りあるが、明らかに答えを改善しない場合スキップすることでになる。なぜなら、偶数番目の値を決めるごとに、奇数番目の値としては余分に操作が必要ないもののうち出現回数最大のものしか見なくてよいから。
RMVNUMBERSは難しかった。相手の選択によらず適切に動いてを空にできるか考える。これまで出現した値のLCMを今見ている値が割り切った場合、またはそのLCMがを超えた場合にそうなるので、操作回数がある程度あればよさそう。2べきが昇順に並んでいる場合が最悪ケースのはずで、これでも50回も操作すれば十分。つまりのとき、先手も後手もやろうとすればを空にできてしまうので、答えは必ずとなる。
あとはの場合が解ければよい。を単純にvectorで持って再帰した。一段階再帰するたびにで割り切れるか否かでが完全に分かれるため、各深さにおいてvectorの長さの総和がとなる。よって、空になったらさっさとを返すのに注意すればが達成される。コンテスト中は何を考えたかメモ化してしまい、0.49sec。この問題のTLは0.5secなので本当にギリギリ。日記を書いているときにこのメモ化が必要ないことに気づき、消して出しなおしたら爆速になった。
UNFRIENDLYは謎。どうせ持つべき候補が少ないタイプの問題だろうと思って、列の長さがまたはなペアしか持たないようにしたら全然合わなかった。この下限をどんどん引き下げて何回も提出してみたが、TLには間に合っているもののWAのケースが全然減らない。そもそものケースですら盛大に間違えている。手元でランダムケースを作ったらすぐ落ちて、ようやく何がダメだったのか気づいた。
のときの繰り返しパターンは2種類しかない。序盤でそのうち片方が一定以上優位に立ったとき、そこからもう片方のパターンに切り替えられないようだ。そこで、あるペアを持つか決めるときに、対応する列の長さが以上という条件のほかに、すでにペアを持っている場合も持つとするコードを書いてみた。とりあえずのケースでは正しく動くはず。これで提出したら、なんと満点を取れてしまった。
残りは部分点。LCAINTERACTは直径を一つ求め、その端点の一方が根でないことを確認した後、そこから根がどれだけ離れているか二分探索で求め、その距離にある点の集合を半分だけ聞くのを繰り返して実際の根を特定するというコードでクエリ回数12回を達成した。直径の端点が根になってしまった場合に次数の頂点を使った。中心を使うともうちょっと減らせそうだったがWA。BNDSPANTREEは区間スケジューリングで部分点1のみ。
合計481点で9位、レートは2799→2832(+33)、highest。BNDSPANTREEは明らかな必要条件からとを調整するだけで区間スケジューリングの順序と辺の重みの順序が噛み合ってうまくいくらしい。すごい。パスに対するクエリに答える必要があってHLDを使いそう。自分もそろそろ履修しなければならない。
種類Aの各辺について、Rの値を(その辺を含む種類Bの辺のRの最小値-1)として、逆に種類Bの各辺についてLの値を(この辺が含む種類Aの辺のLの最大値+1)とすると、区間スケジューリング問題をするだけで勝手に条件を満たしてくれる(!)
— heno (@heno_code) 2022年9月23日
適当に実装したらlog1個でもTLEして、定数倍高速化をするはめに
UNFRIENDLYの解法の正当性がよくわからない。下のツイートを元に考えてみる。持つか持たないか迷っているペアが発生するとき、であるから、今のところ最適とされている選び方の直近四つがと取れる。ここでかもしれないが今は異なるとする。候補として確実に持っているのはで、この三つのうちどれにも繋げることができないのはのみ。
実際、今確実に持っているペアを反転してみると、挙げた二つはそれぞれに繋げることができる。しかしわざわざこのペアを選ぶ必要はないので、なぜこれだけチェックしておけば十分なのかがわからない。例えばならというすでにあるペアにを足すことで再現できるため問題ないと言えるものの、のほうはどうやって吸収されているのか本当にわからない。
ちなみに、こういう考え方は以上を持つとしても同じところまで進める。なんと条件をこれに強めてもACしてしまった。ではさすがに落ちた。
セグ木関係なく解ける
— heno (@heno_code) 2022年9月23日
今考えている数列の最後2項の候補が(a_1,b_1),...,(a_m,b_m)になっているとする。ここに新しく候補(A,B)を入れたい時、「あるペア(C,D)が存在して(A,B,C,D)はvalidだけど(a_i,b_i,C,D)は全てinvalid」の時だけいれてよい(そうでなければ入れる意味がない)
これを保つと実はmが小
食事して午前4時からTCB51に参加した。
https://techful-programming.com/user/event/3235
3問目はこの位置としては難しめに見える。ずらす幅を全探索し、対応する要素の差を足し合わせる。4問目は前から貪欲に操作しなければならない。5問目はの和をと書き直す。の符号を見れば答えの候補は高々二つだが、念のためを全探索した。
7問目はかなり面倒。ある頂点の親をにするのが最適で、変更した頂点を根とする部分木に対するのはその場で計算、他の頂点のそれは全方位木dpのように計算して伝播してきた値を使った。
8問目は謎。最初にのdpで値の種類数がの数列を数え上げる。種類数が未満の数列は必要な値をすべて含むような列ならどれからでも作れるが、そのような数列の数え上げにも今計算した値が使える。種類数がちょうどの数列はそれ自身からしか作れない。
9問目は区間dp。10問目はと決め打つとのdpが書ける。まだ決めていないの要素数を持つことにして遷移をの値で場合分けしてみると、の場合はをで行い、の場合は、だけ計算して残りは全部にするという遷移になることが分かった。シンプルでいかにも速そう。これを実装すると、最悪ケースである全部のケースも手元で2.5secになり、提出してみると3.7secで通った。
理論値。時間は50分弱で、各問題ともボーダーまでかなり余裕がある。10問目はまたしてもTL 5secを悪用して定数倍高速化で通してしまった。改めて考えてみたところ、の場合の遷移を遅延させることでの非ゼロ要素が高々2個になり、具体的な値の取得も定数時間で行えてを決め打つごとに計算量が達成できた。あまり見ない高速化で面白かった。
このあとYouTubeとネット小説に1時間ずつ時間を吸い取られてから日記を書き始めた。午前11時に切り上げてから少し読書。本を1冊読了。
「虚構推理 逆襲と敗北の日」。長編、ただし最初に短編のようなものが一つ付属していた。ちょうど解決シーンに入るところで数日読むのが止まっていたためちょっと没入感が薄い。そもそも解決自体割とあっさり目で、サブタイトルの意味もそこにはなく、続く主要キャラクターたちのやり取りがメインだった。この部分は興味深かった。岩永琴子はもうちょっと非人間的な性質だと思っていたのにそうではないようでびっくり。がっかりもしかけたが、その分は桜川九郎でバランスが取れているらしい。
ネット小説を読んで午後1時半就寝。
09/24(土)
午後8時半起床、午後9時からABC270。
TOYOTA MOTOR CORPORATION Programming Contest 2022(AtCoder Beginner Contest 270) - AtCoder
Aはbitwise ORを出力する。とりあえずRakuで書いたあと、もっと短くならないか4分ほど試行錯誤していた。
B問題は難しい。まずとなるように適切に符合を反転しておく。のとき壁を破壊する必要があって、ならハンマーを拾いにすら行けないため。そうでなければである。そもそも壁を破壊する必要がなければ答えはそのままとなる。丁寧に確認していたらかなり時間がかかった。
Cはから祖先のリストを管理しつつdfsし、にたどり着いた時の状態を出力。Dはdp。Eは何周するか二分探索し、残りをシミュレート。Fは港と空港用の超頂点を用意し、その二つを連結成分に含めるか22通り全探索してそれぞれ最小全域木を求める。
Gはと書ける。は別に計算することにすれば、和を閉じた形にしてとなる。これがに等しいので、、と置きなおすとが求めるの条件。は場合分けにより、それ以外はをBSGSで解くことで答えが求まる。
Exは難しい。しばらく唸っていたら綺麗な表現を見つけて一気に解けた。カウンターの操作を、初期値であるような値をデクリメントするかとするかで表し、状態をで定める。この値がになるまでの期待値を求めたくて、遷移はカウンターを操作するときと書ける。これでループのある期待値dpに帰着できそう。
を状態からに遷移するまでの操作回数の期待値とする。とおいて、dpの値をすべての一次式で表す。に対してとなり、なるの個数とそれに対するの和が求まっていれば、適切にから引いたりを足したりして計算できる。
最終的にという形で書けて、とは次にとなるまで変化しないので、その間の遷移をまとめて行うことができる。これによりのみ求めるのが十分高速。最後にからの値を求め、にそれを代入したものが答え。
本当にを求められるのか、つまりにおけるの係数がにならないか不安だったが、エイヤと出したら通った。ではどんな値になるのかということでコンテスト後に式を追ってみたが、複雑すぎて断念した。
全完3位、日本人2位で賞金10万円。1時間ちょっとで全完したので時給10万円らしい。こんなことならAでコードゴルフしてなければよかった、と思ったが、実際のところ2位との差は10分以上あってどうしようもない。それより4位との差が2分ちょっとだったことのほうが重要で、B問題を丁寧に解いたことやG問題の式変形のコーナーケースを見落とさずノーペナで通せたことはかなり偉かった。
Gはこういう式変形をしなくても直接BSGSできるらしい。結局のべき乗が同じ形で表せることが重要。解説のBonusは、通常のBSGSを非素数modで計算する場合と同じでを使わず頑張れるという話だと思う。このでもステップくらい進めば周期に入るのだろう。
コードゴルフ。これはMHC後に縮めたものも含む。AはRakuよりAWKのほうが短くなった。Bはと、の間にがあるかで場合分けしていることになって、この「間にある」という条件は例えば(0<Y)==(Y<X)
のように書ける。正確には区間のちょうど端にある場合に注意する必要があるが、今は制約から関係ない。これをAWKで実装したものが最短になっている。
Cは根をとして各頂点の親を求める方法を実装したがコンテスト中の方法に負け。言語はPerl。DはAWKでdpしたらPerlより縮んだ。EはRuby。以降は手付かず。
午前2時からMHC R2に出た。
Meta Hacker Cup - 2022 - Round 2
A1は文字を取り除いたときに文字列の中心になる場所を2通り試して、左右に出現する文字ごとの個数の差が一つだけ、残り全部となることをチェックした。あらかじめ文字ごとに個数の累積和を計算しておく。
A2でも中心を2通り試すのは同じ。その前に列全体のXORを計算することで取り除く値が何であるかを確定させておき、チェックをmultisetのハッシュで行った。値に素数を割り当て、その積をで管理する。このとしては素数をたくさん用意してあり、提出コードでは7個だが、思ったより高速に動作したため手元で18個使っても出力が変化しないことを確かめておいた。ちなみに、原始根を考えることでこれがにおける和を管理しているのと変わらないことがわかる。コンテスト後に気づいて拍子抜けした。
Bは各クライアントに対して上位個のパスを管理する。遷移も、適切な順序でクライアントを見ることで日付ごとに上位個のパスを更新しながら行えるため、十分高速。
Cが解けずDに進んだ。D1は左右の和の差が交換によって、しかされないため、、つまりとの交換を貪欲に行うべき。
D2はとしかないため交換しなければならない個数がわかって、それが個だったとすると、から左に見て個目までのを右に見て個目までのと入れ替える、あるいはこれのとを逆にしたものを行うことになる。個数を管理するセグ木の上で二分探索することで範囲がわかり、その範囲内でインデックスの総和を求めると、差が答えになる。
Bが落ちて64点、178位。オーバーフローしていた。パスの利益はで押さえられると思っていたのに、、つまり高く買って安く売る能無しクライアントのせいで壊れていた。
オーバーフローしてた。Yi<Xiなクライアント全員バカです(バカバカバカバカ)
— こたつがめ (@kotatsugame_t) 2022年9月24日
朝までC問題と格闘していた。はかりの左右どちらに乗せるかが重要だと思っていたが、対称性から無視できるらしい。とはいえ解説のこの部分はサラッと流されてしまっていたので、自分で説明を加えた。計算量は少し悪くなったものの間に合うオーダーに落ち着いたので満足。まずと同じ重さのクッキーを1個以上はかりに乗せる確率を求める部分について、これは単に選ぶ順番通りを全部キャンセルしているだけなのでcombinationでよい。
次に、と同じ重さのクッキーを個使う場合について考える。このケースに制限すると解説の文言が納得できた。個をどのタイミングで選ぶか決めるごとに、そのうちどの位置に置かれたものが最後まで残るか一意に決定して、そこに置かれる確率は個どれでも等しくになるのだ。これによって、相変わらず選ぶ順番通りをキャンセルしてよいことがわかる。選び方を数え上げ、すべてのに対して和を取った後、で割ることにしよう。
個のうち個がバッチ1由来である場合を考えると、まずこれが起こる場合の数が通り。そのうちが当たりなので、これを掛けて足し合わせたい。Wolfram|Alphaに投げるとうまいこと閉じた式にしてくれて、になった。は全探索できるので、これで解けている。
しばらくABCのコードゴルフの続きをした後、昼前から日記を書いていた。金曜日のCodechefの部分に差し掛かって、UNFRIENDLYを通した自分の解法の正当性が証明できず、布団に逃げ込んだ。午後3時就寝。
09/25(日)
午後8時半起床。午後9時から久しぶりのTOKI、TROC #27。
https://tlx.toki.id/contests/troc-27/
Aは列に偶数が含まれているか調べる。Bはそれより大きい最小のまでインクリメントし、一気に消すのが最適。
Cはインドネシア一流の謎パズルで、とそのとを入れ替えたもののを提出して1WA。を考えて右上と左下を結ぶ線の上以外を暗くすることが可能だと気付いた。答えは。
Dはやたら合わせるのに時間がかかった。の場合は自明。の場合、「先頭がで隣接項の差が以下の長さの順列」をに対して前計算しておけば、適当に足し合わせることで答えになる。この前計算は挿入dpを考えるのが正解だったらしい。隣り合う2項を交換するか決めるだけではのような並び方を生成できない。
Eはという制約に気づかず1WA。しばらく実験して、以下で最大のと、ならそれも聞くことで特定できることに気づいた。前者によってを、後者によってを区別できている。
Fは面白い。好きな辺を選んでそこまで往復することでウォークの美しさをすることが可能。これでユークリッドの互除法を行えるため、としてで割ったあまりを求められる。この時点で、とりあえず根を一つ決めて各頂点までのパスの重みを求めておいた。それをとすればである。より上のキャンセルもに吸収される。
を、、に分類するのは難しいな、と思っていたが、冷静になるとなのだから、はまたはだった。これならをに置き換えるだけでよいので簡単。
Gも面白かった。実験すると回コピー後に値は個あることがわかる。この値はと等しく、先頭から個は1回コピーをキャンセルしてもで、残りはになるということがわかる。このことから、をデクリメントしながらとを丁寧に更新するの方針が得られる。ただしcombinationは適切に差分更新を行う。
がとんでもなく大きいと困る。しかしですでにからとなるため、では十分間に合いそう。よってのケースさえ別に判定すればよく、この部分は実験で容易に解ける。
Hは解けず、7完8位でレートが2732→2762(+30)。highest。
10分のインターバルで午後11時半からCF #823 div.2。
Dashboard - Codeforces Round #823 (Div. 2) - Codeforces
Aはよい。Bからすでに難しかった。でソートしとなる場合を考えるのを繰り返す。はかどうかによって絶対値記号を外せるので、それぞれ外す。の項を除いて適切にやを求めるのは、あらかじめ左右から累積的に計算しておける。これを使うと最小化する値がのような形になり、二つの値が等しい場合に最小値を取る。
Cは簡単。後ろから見て累積とならない位置の文字は動かすべきで、それもちょうど1回動かすとしてよい。するとどんな数字に変化するかわかり、残した累積の広義単調増加を壊さないような位置に挿入するのが最適になる。
Dは信じられないほど難しかった。ずっと実験で文字がどう入れ替わるか観察していたが全く光明が見えない。ふと不変量について全く考えていないことに気づき、その気持ちになって眺めると、の文字目との後ろから文字目がペアとなり、必ず異なる文字列に入ることに気づいた。ペアの列を並び替えたり、要素の順番を逆にするのは自由にできると信じる。
もし文字a
とb
のペアが二つあれば、文字列における対称の位置、例えば先頭と末尾に置くことでそのインデックスを揃えることができる。同じ文字のペアが奇数個しかない場合、それがa
とa
のような形をしていれば文字列の中央に置ける。逆に、異なる文字のペアだったり、文字列の中央が埋まっていたりするともうダメ。この判定を書いたら通った。1時間かかったらしい。
次により多く解かれていたFを考え、bitDPをしても見るべき状態数が少ないから間に合いそうだと思ったが、とりあえず書いたらサンプルが合わず、そのままコンテスト終了。4完。かなりの大失敗だった。Bはの位置にかまわずとして展開してしまう方法が賢い。コンテスト中のようにとを使った形に整理できる部分は同じながら、の範囲が制限されておらずここから即座に答えが出る。
コンテスト後にFをupsolveした。まずbitDPの説明から。インデックスを見ているとき、としてここに置ける値の範囲を考えてみる。まず自分より左に個の値があって、これらはすべて以下である必要がある。そのような値は自身を除いて個しか存在しないため、よりが得られる。同様のことが右に対しても考えられて、もわかる。
つまり値をこれまで置いたかどうか記録しておかなければならない情報が個分、はインデックスで初めて置けるようになった値なので、正確には個記録しておけば十分で、bitで表現できる。
端を除けば個のうちちょうど個が埋まった状態しか考えなくてよい。で計算してみると通りだった。これで出してもTLEしてしまうが、ここで「また値を置いていないのにより大きな値が置かれている」という状態をちゃんと無視することで十分高速になった。値を置くときにダメだと気付くのでは遅く、状態数が多くなりすぎるようだ。そのほか、転倒数をあらかじめに対して計算しておくなどする高速化を入れて提出すると、1400msで通った。
TCB51の結果が出ていた。理論値は3人いたが時間差で優勝。10問目を非想定で押し通しているとはいえ、2位と20分以上差をつけていて気分がいい。
来週水曜日にたいぺーとホスフィンと3人で家で飲む予定。いつもはドンキでお酒を購入するのだが、今回はAmazonで見繕ってあらかじめいくつか購入しておくことになっていた。ギフト券残高の消化。これの希望が出そろっていたので、しばらく時間を使ってそれが本当に最安値か調べたりした後注文した。
午前4時から午前11時まで月曜日のインターン先勉強会のための発表スライドを作っていた。内容は考えてあったので今日一日で何とか完成。
途中でRating Historyを確認したらAtCoderとCodeforcesのAC数が両方ほぼキリ番だった。
Solved By kotatsugame
— こたつがめ (@kotatsugame_t) 2022年9月26日
Topcoder: 145
Codeforces: 2003
AtCoder: 3999
AOJ: 1322
yukicoder: 1469
library-checker: 25
Sum: 8963
https://t.co/0nO54qH8aU
AtCoderがほぼキリ番に
生協に行って菓子パンやラノベを購入し、正午就寝。