2023年12月30日土曜日

Codeforces Round 918 (Div. 4)

 全完。

コンテスト後のツイート


 Eの方がFやGより簡単な気がしたけど、解かれた人数を見ると正しい順番で並んでいたみたい。ちょっと不思議だった。

 とはいえ、Eに時間かかり過ぎている(多分、20分以上かけている)。

 Eは、解法をすぐに思いつかなくとも、

 具体的な解き方が分からなくても、累積和を活用する問題だろうとは想像できる
→ 偶数、奇数について累積和を書いてみる。
→ 区間和が一致するときはどういうときか眺める

 という流れで解けるし、実際コンテスト中もこの流れで解けた。

 頭の中で累積和をどう活用するかが分からず、累積和を書くまでに10分くらいかかっているのは良くない。頭の中で考えるのが悪いわけじゃないけど、累積和を使いそうと思ったら累積和を使うところまでは書くべきだった。

2023年12月28日木曜日

RECRUIT 日本橋ハーフマラソン 2024冬(AtCoder Heuristic Contest 029)

 pretest76位→最終96位でした。

コンテスト後のツイート


 システムテストで20個も順位が落ちて、最後の最後に提出しなかったら……、と、ショックを受けたのだけど、あとで調べたところ、どれを提出してもほぼ変わらなかったらしい。

 順位としてはそう変わらないとしても、60位→100位だったらもっとショックを受けていただろうからこれで良かったのか。

 その一つ前の提出なら順位は変わらないけれど、ベストを二つ取れていた。

 これを踏まえると、自分の提出はどれも、箸にも棒にも掛からないものが大半だが、一部のケースで評価関数がうまくはまると高得点が取れる……というものだったよう。それも、元の得点の低い、増資回数の少ないcaseで起こっていたようだ。

 いやー、そう気付くのは難しいね! そして、結局どれも同じくらいの順位だったのだから、それに気付いてもどうしようもなかった。
 なお、提出候補だった三つはlog(元のスコア)の総和ではほとんど変わらないものたちだった。この指標、どれだけ信じて良いか分からなかったのだけど、結構信じて良いのかもしれない?



 なお、昔の提出をしていたらシステムテストで何位だったか? は、wataさんの詳細順位表を利用しています。
 Usageの「ローカル版」にある通りhtmlを保存し、input.csvとresult.csvは、
https://img.atcoder.jp/ahc_standings/ahc029/input.csv
https://img.atcoder.jp/ahc_standings/ahc029/result.csv
 から手に入れました。



2023年12月24日日曜日

Pinely Round 3 (Div. 1 + Div. 2)

 Cまで三完でレートを大きく落とす。

コンテスト後のツイート


 D. Split Plus K

 解法ツイートを見てAC。

 目標の値をa, 操作回数をxとしたとき、

・a=(A[i]+k*x)/(x+1)

 となる。この式をずっと睨んで、(A[i]+k*x)/(x+1)=(A[i+1]+k*y)/(y+1) とか色々変形したりしてたけど、kをくくりだして

・a=k+(A[i]-k)/(x+1)

 とすると良かった模様。
 確かにこうするとaがA[i]-k達のgcd+kになることが見える。

 言われてみれば普通だけど、こういうのを思いつかないのが式変形のセンスのなさかなぁ。今見ても難問に思えるので、まあ仕方ないか。
 

2023年12月21日木曜日

Codeforces Round 916 (Div. 3)

 Gが解けず。G1を終了二分後にAC。

コンテスト後のツイート

G2. Light Bulbs (Hard Version)

 この解説の方法でACした。

 区間に値を割り振り累積xorを取ると、0のところで区間が完全に分かれるので、最低何個点灯させればよいかは分かる。
 さらに、「同じ値が二個出てくる区間」について考えると、これも他と独立していることが分かるので、そうでない部分のindexの個数を掛け合わせれば良い。

 なお、ちゃんと理解していないが「区間に辺を張るテク」(セグ木を使うもの。検索すれば出てくる)でも解けるらしいので、こちらでも書けるようになっておくべきか。




2023年12月20日水曜日

AtCoder Grand Contest 065

 A一完。五連続でレートを落とす。

コンテスト後のツイート

B - Erase and Insert

 後ろからDPというキーワードを見てAC。
 後ろからDPで解けると言われたらそれほど困らずに解けた。

 コンテスト中もまず、後ろから見ることを考えたのになんで解けなかったのだろう? と思い出してみる。
 Aで詰まったときBを考えていたのだが、前後から見てどう変化するかを手で書いた後、シミュレーションのコードを書いた。その後、Aに戻ってACした後Cへと行ってしまった。

 ということで、「実験コードを書く」という手を動かすことはしたものの、後ろからDPでいけるのでは? というのは真面目に検討していなかったと思う。

 手を動かすだけで満足せずちゃんと考えていれば解けた気がする。特に、この問題がCodeforces(Div. 2)のDあたりに置かれていたら解いていた可能性が高い。これは自分だけでなく、この問題は、そのあたりに置かれていたらもっと多くの人に解かれるような難易度だと思う。
 AGCだから、と変な心持ちになっていないか。反省したい。

C - Avoid Half Sum

 解説を見てACしたが、どうすれば思いつけるのか分からない。

 実験するしかない気がするが、実験しても分かるのだろうか……。ただ、もっとちゃんと実験すべきだったとはいえるか。

2023年12月17日日曜日

トヨタ自動車プログラミングコンテスト2023#8(AtCoder Beginner Contest 333)

  Eまで五完でさらにレートを落とす。

コンテスト後のツイート

F - Bomb Game 2

 三乗DPはまあまあすぐ分かったけど、遷移の式を見て高速化できない気がして、「別の方針で二乗になるのかな?」と思ってしまった。
 でも自分は三乗しか思いつけなそうだから埋め込みを試みよう、と思ったが思ったより埋め込む個数が多くなりそうで困り、C++へ書き換えたりとかしているうちに時間切れ。

 落ち着いて自分の書いた式を見返せば、確かに二乗に落とせた。
 埋め込みしようとか考えず計算量を落とすことに集中していれば解けた気がしないでもない。

 Unratedで出ているときと違い、Ratedだと雑念も混じってしまうしね……。

G - Nearest Fraction

 解説AC。

 Stern–Brocot木を使って小数を既約分数で近似する問題。知識問題という感じですね。Pythonではライブラリでも解けたようだけど、実装もそれほど難しくない。

 まずleft=[0,1],right=[1,1]としておき(第一要素が分子、第二要素が分母)、mid=[left[0]+right[0],left[1]+right[1]]とrの大小を比較する。
 そして、たとえばmid<xならばleftを更新したいのだが、その際、[left[0]+k*right[0],left[1]+k*right[1]]が条件を満たすような最大のkを求め、それで更新すれば良い。

2023年12月13日水曜日

Kotlin Heroes: Episode 9 (Unrated, T-Shirts + Prizes!)

 60位でTシャツ圏内に入れず。悔しい。

コンテスト後のツイート

H. Sum of Digits of Sums

 この問題とかなり似た問題だった。

 似た問題を解いたことがあるとは思ったし、そのおかげで解法も思いつけたのだが、ここまで似た問題だとは思っていなかった。最初に検索したらコンテスト内に解き終ったかもしれないね。

HACK TO THE FUTURE 2024 (AtCoder Heuristic Contest 027)

 pretest121位→システムテスト118位でした。

コンテスト後のツイート


 解説放送を見たら、理想的な周回ペースとしては1/√dおきに周るものだ、という話をし、それを使っていた。これは金曜あたりまでずっと考えていた内容だったのに、点数が伸びず断念したものだった。思いついていたのに使えなかったのは残念。

 なお、数学的にではなく二分探索で求めた(ので、比率は同じだが、1/√dに比例するとは気付いていなかった)。

AtCoder Beginner Contest 332

  Eまで五完。Fが約一分間に合わず。

コンテスト後のツイート

F - Random Update Query 

 非可換な場合の遅延セグメント木をあまり書いたことがなかったため時間をくってしまった。抽象化した捉え方ができておらず、どのノードで何が起こっているか、みたいなことを考えないとできないのが時間がかかっている原因だと思う。ちゃんと抽象化を理解すべきか。

 なお、双対セグ木でも解けるという解法ツイートを見たが、よく理解できていない。自分より上のノードを毎回更新すればできるってことかな? それなら理解できるが、そういう双対セグ木を書いたことがないので、どっちみち時間がかかったと思う。

estie プログラミングコンテスト2023 (AtCoder Regular Contest 169)

  AB二完で青に落ちる。

コンテスト後のツイート


 C - Not So Consecutive

 解説AC。

 コンテスト中は、DPでやるなら「各数字iについてj回連続しているvalidな個数」を各indexについてもたなければいけないから無理そう→包除原理を使うのでは? と考えていた。
 実際包除原理でも解けたらしいが、自分の実力では難しそう。

 ただ、DPで解けたかというと、解説を見て、DP[i][j]をindex iでjで、index i-1でjでないvalidな個数、DP2[i][j]をindex iでjなvalidな個数としたとき、

・DP2[i][j]がDP[l][j]+DP[l+1][j]+...+DP[i][j]という形で表せる

 というのを見て全く意味が分からず十分以上考えてしまったくらいだから、思いつけた可能性は低そう。
 ある数を連打しているときは、その個数は変わらないのですね。言われてみれば確かにそう。

 そして、その後の実装も苦戦した。

 DP2[i][j]を累積和で表したいが、その途中に-1でもjでない数が現れていると、そこまでの和にしなくてはいけない。なので、最後に-1でない数字が表れたindexを二つ保持しておく必要がある(と思うけど、解説に言及されてないし、ここに気を配らずにやる方法があるのか?)。このことになかなか気付けなかった。

D - Add to Make a Permutation

 解説AC。

 解説を追うこと自体は難しくないが、条件を整理・きちんと立式することが求められている気がした。理解して実装したつもりが答えがなかなか合わず、自分でもう一度式を整理し書き直してAC。
 しかし、実装に中国剰余定理が必要になったりしたが、本来の解答では使っていなさそうなので、まだ何か勘違いしているのかも。

2023年11月25日土曜日

yukicoder contest 413

  A一完。Bでハマってしまった。


No.2542 Yokan for Two

 自力AC。この後のCodeforcesをやっている途中で気付いた。
 コンテスト中は、制約からDPだと思うも、最後に切った位置とかもたなくてはダメだから解けない……などと悩んでいた。

 最初と最後どちらに使うかを決めれば、後は自由に決められる。なので、普通にDPできる。
 思いつかなかったのは悔しいが、ARCのAとかで出てもおかしくない問題だと思うので、ratedじゃなくてここでハマって良かったと思うことにしよう。

No.2543 Many Meetings

 自力ACはしたが実装に大いに苦労した。

 区間スケジューリングは考えたのだが、あるミーティングの次のミーティングを選ぶ部分を平面走査的に考えたのが苦労した原因か。
 そこでdictを持ち出したりしたため、後のダブリング部分の実装も面倒になってしまった。

2023年11月24日金曜日

AtCoder Regular Contest 167

 二完遅解きで青落ち。
 Bで、多倍長を利用してそのまま計算しても通ったという話を聞き、そうしていれば青に落ちることはなかったのでは、とは思うものの、それで通ると判断できなかったのも実力ですね。

コンテスト後のツイート

C - MST on Line++

 こたつがめさんの放送の振り返りを見てAC。

 難しい。
 各辺のコストが何回ずつ使われているか? を計算しようという方針自体は最初に思いつくものだが、どうやって計算すれば良いかが難しい。

 最初のとっかかりは、「一回最小全域木を作るとき、各コストは高々二回しか使われない」というところだろう。これに気付けば、0~2回それぞれの回数使われるときのpermutationの個数を考えようという方針が湧く。
 しかし、これを思い付いた後も各条件を見つけるのが大変だし、その後詰めるのも難しかった。

2023年11月21日火曜日

ALGO ARTIS プログラミングコンテスト2023 秋 (AtCoder Regular Contest 168)

 Bまで二完。Cは方針はあっていたので悔しいが、こういうのを詰めるの時間がかかってしまうんだよなぁ。

コンテスト後のツイート

C - Swap Characters

 自力AC。コンテスト中に書いていたコードをもう一度眺めてみたらどこを修正すれば良いか分かった。

 まず、A、B、Cの個数だけ見れば良いことは分かって、その上で、

・"A"を何個交換するか決める(aとする)。さらに、"A"と交換する"B"の個数を決める(bとする)。このとき、"A"と"C"の交換する個数はa-b個。

 これで"A"と何かを交換するのは終了。

・元々"A"があった位置にある"B"、”C"内で交換する必要はない(どの位置と交換するか選べるので)。ただ、元々"A"があった位置にある"B"や"C"の個数を増減させたいことはあるので、何個増減させるか決める。

・あとは、今までで交換していない"B"と"C"の交換を考えればOK(他のものについては、交換した後の場所で自由に動かせる)。それらを何個交換するか決める。

 この手順で探索して、各ステップで「何個ある中から何個選ぶのか?」を二項係数で書いた掛け算していく。それだけといえばそれだけなのだが、手順が複雑だと時間がかかってしまう。

D - Maximize Update

 解説放送を見てAC。

 コンテスト中、区間DPか? とは少し考えたけど、具体的にどうやれば良いかは全く分かっていなかった。言われればなるほど、という感じではあるけど、判定問題もそう簡単に解けた気はしないので、Cに集中して正解か。





2023年11月12日日曜日

トヨタ自動車プログラミングコンテスト2023#7(AtCoder Beginner Contest 328)

 Fまで六完。Gも解けなくてはいけない問題でした。

コンテスト後のツイート

G - Cut and Reorder

 解法ツイートを見てAC。

 bit DPだとは思ったが、どういう遷移なのかパッと分からず時間を浪費してしまった。Aの番号が小さい方から使っていくという、自然な遷移を考えれば良かったのだが。

 一番の難所であるはずの、メモリの制約が特殊だというのも気付いていなかった。適切なbit DPの遷移を思い付いていれば、メモリを節約するDPを思い付くのも難しくはない……とは思うものの、コンテスト中にこれができたかは分からない。

2023年11月11日土曜日

yukicoder contest 412

 Bまで二完。


No.2535 多重同値

 自力AC。

 コンテスト中、上手い式変形があるのか? と考えて分からないまま眠ってしまい、起きたらDP(メモ化再帰)でいけると気付いた。眠いとき、簡単なことでも思いつかないのは仕方ないですね。
 ただ、その後の実装で添え字など間違えて苦労したのは良くない。

 そして、解説を読むと、式変形でも解けると書いてありました……。

No.2536 同値性と充足可能性

 自力AC。

 Union-findでつないだ後、二部グラフの判定をやればOK。
 問題内容を正しく理解できればあとは典型だけど、結構面倒くさいね。

No.2537 多重含意

 自力AC。

 古典命題論理で、p_1→p_2→……→p_nが(p_1⋀p_2⋀……⋀p_n-1)→p_nと同値だということを知っていれば簡単。
 簡単に解けるのならコンテスト中に解けよ、とは自分でも思ってしまうが、問題文を読んでなかったからねぇ。

2023年11月6日月曜日

トヨタ自動車プログラミングコンテスト2023#6(AtCoder Heuristic Contest 026)

 56位。短期ヒューリスティックとしては悪くない順位なのだけど、もっと上にいけたはずなので悔しい。

コンテスト後のツイート

 本当に上位の解法は、「各山ごとにソートする」だったようだ。これは全く頭に上らなかったわけではないけど、あまり検討しなかったから仕方ない。

 自分の方針でももっと上位にいけた、というのが悔しい。

 まず、RUSTに直すところ。
 エラーメッセージもないのに、実行しても何の出力も返ってこないので不思議に思っていたのだが、こんなミスをしていた。

 いやー。くだらないミスなんだけど、意外と気付きにくいか? どうしたら気付けたのかなぁ。


 ただ、本質はもう一つの方です。

 ツイートの「焼きなまし」における遷移は、「x以上を山yに移す」を「x以上を別のランダムな山rに移す」に変更するというのだけ行っている。その後、スコア計算を愚直に行い、改善されていたら採用、もしくは、焼きなましの条件式を満たしていたら採用、としている。

 その条件式が間違っていた。

 なぜこんなミスを……。

 思い返すと、まずPythonで山登りを書いて、焼きなましに直す際、RUSTに直そうかな、と思ってちょっとだけ書き、「いや、もし間に合わなかったら嫌だからPythonのままで改善するか試そう」と思ってPythonでも焼きなましを書いたんだよね。

 そのとき、RUSTの焼きなましの式を見ながら書いたから、コピペでなくちょっと自分で直す必要が生じて、それで間違えたのだろう。

 その後、そのPythonの式を見てRUSTに直したから、間違いがそのまま残ってしまった、と。


 とはいえ、焼きなましの意味を理解していればこんなミスはしないはずですよねー。

2023年11月4日土曜日

yukicoder contest 411 オムニバスコンテスト

 Dまで四完。


No.2529 Treasure Hunter

 自力AC。

 各行にある宝の個数を決めれば、次の行に宝を0/1/2個おくそれぞれの配置の個数が決まる、という大胆予想をして実装したら当たっていた。

 コンテスト中も一度こうじゃないか? と考えたのだけど、違う気がして再度別の方針を考えてしまった。実装が簡単なので、ratedコンテストならとりあえず実装してACはできていたと思う……。

 一個以下ならこの予想は当たり前なのだけど、二個のときが分からなかった。
 公式解説を見ると、立式してみれば証明できるみた。うーん……でもこれは予想した後でないと考えない立式&証明なので、この予想を思い付いた時点で実装してsampleが合うかを実装して調べるべきでしたね。

 一旦考えたことを、あまり検証せずに捨ててしまうのはダメ。

No.2530 Yellow Cards

 自力AC。

 もっと高速化できるみたいだけど、O(N*K)で良いのならDPで良いですね。

No.2531 Coloring Vertices on Namori

 自力AC。

 閉路の部分はDPをし、他はK-1をかければOK。これはすんなり解けた。

No.2532 Want Play More

 自力AC。珍しく再帰で実装した。

 全問通してみると、一番難しかったのはE問題だった(writerの名前を見たら予想できたはず……)ようで、全完するチャンスが十分あった回だったのですね。

2023年10月29日日曜日

パナソニックグループ プログラミングコンテスト2023(AtCoder Beginner Contest 326)

 Dを飛ばしてFまで五完。

コンテスト後のツイート

D - ABC Puzzle

 自力AC。

 Rの条件を満たすボードが20の五乗なので、これを全部作って調べようと思ったのだが、これだけだとTLEしてしまった。Cの一行目を満たすかどうかで枝狩りしたら通った。

 間違った方針ではないだけに、コンテスト中、時間があったとしてもこの方針に拘泥してしまった気がする。結構時間を残していないと通すのは厳しかったかも。

G - Unlock Achievement

 解説放送を見てAC。

 フロー(それも「燃やす埋める」の変形)だと分かった上でまあまあ長いこと(二時間くらい?)考えてもグラフが構築できず解説放送を見た。

 各スキルについて、「ゴール→レベル1→レベル2→……→レベル5→スタートとINFの辺を張る」、というあたりを思い付いていなかった。頂点倍加が必要? とかもっと複雑なグラフを考えてしまった。
 言われてみればなるほど、という感じではあるのだが……。

2023年10月28日土曜日

yukicoder contest 410

 Cまで三完。


No.2518 Adjacent Larger

 自力AC。全く条件が分からなかったが、ランダムテストを書いて実験して……を繰り返したらACできた。
 与えられたAに対して、1が連続する部分を圧縮したものをBとしてたとき、

・B中に2が連続するところがあったらダメ。
・B中に、[2, 1, 2]もしくは[0, 1, 1]という部分があったらダメ。

 でした。

 公式解説を読むと、なるほど確かに、という感じ。
 実際に元の数列を求めようとは考えたのだけど、2(や0)のところから考えれば良いとは思いつかなかった。

No.2519 Coins in Array

 自力AC。f(x, y)は実験して予想した。

 ただ、0になるときずっと(1, 2)をし続ければ良いというのは気付かなかった。f(奇数, 奇数)が偶数になり、f(偶数, 偶数)=0になるので、高々3ターンで0ができ、それを使って他のものを0にしていった。そのためやや面倒な実装になってしまった。

No.2520 L1 Explosion

 自力ACだけど、タグを見たし、実装問題だからね。時間をかければ解ける。

 ただ、最初座標変換せずとも解けるか(斜めにimos法をすれば)と勘違いしてしまった。(少なくとも単純な二次元の)imos法は長方形にしか使えないので、x'=x+y, y'=x-yのように座標変換しないと使えなかった。
 実装してこのことに気付いたのはちょっと間抜けだった。

No.2521 Don't be Same

 自力AC。

 頭の中で色々試したら(1, 2), (3, 4), (5, 6)のときだけ負けに思え、実装したらACできた。こういう問題は大体いつも実験しているので、実験せずに分かったのは嬉しい。

No.2522 Fall in love, Girls!

 タグは見たけど自力AC。

 bitDPというタグを見て制約をちゃんと見たら種類数が20というのがあったので、あとは実装問題でした。

 ただ、後半に

「1, 2, .... , nと番号のついたn個の玉と1, 2, ... , kと番号のついたk個の箱があります。番号順に玉を取り出し、順番に箱につめていきます。ただし、まず1の箱をつかい、次に2の箱を使い、……と、箱も番号順に使います。一個も玉の入っていない箱があっても構いません。玉の詰め方は何通りでしょう?」

 というような問題が現れ、kが小さいからDPで解いてしまった。これ、ただの二項係数ですね。気付かなかったのは恥ずかしい。

No.2523 Trick Flower

 タグを見て自力AC。

 SCCしてDPする問題。
 そこまで分かれば実装するだけかと思ったら、トポロジカルソートの順番を逆順にしてしまいWAが出て、しばらくどこが間違っているか分からず困った。
 SCCした後木DPをするのだから、SCCした後のグラフをちゃんとイメージしなくてはいけなかった。

No.2524 Stripes

 解説AC。

 二乗のDPの式を立てるのは簡単。それを形式的ベキ級数で解釈すると、分割統治してFFTを使いながら行列計算することにより高速化できる。

 行列に多項式を入れて計算すると高速化できる、というのは初めて見たと思う。それぞれの解法を知っていれば何をしているか理解するのは難しくないが、自力で解くのは結構厳しい気もする。
 

2023年10月25日水曜日

yukicoder contest 409

 Aを解いた後AHCをやろうと思っていたのに、AHCもやらずに眠ってしまった。


No.2509 Beam Shateki

 自力AC。

 x行とy列にビームを打つならば、x行目とy列目の和を前計算しておいて、その和からA[x][y]を引く。

 ……この方針で実装したが、実装量が多くなってしまった。
 今回は、ビームの位置を全探索し、毎回愚直しても間に合う。その方が実装が簡単だったか? でもあまり変わらない気もする。

No.2510 Six Cube Sum (Count)

 自力AC。

 半分全列挙は思いついたけど、メモリ制限が厳しく実装に苦労した。

No.2512 Mountain Sequences

 苦労したが自力AC。

 最大値を固定して考えると、Σ(二項係数)*(二項係数)の形になる。多分、Σの中が高速化できるんだろうな~、とWolfram alphaで実験を繰り返したら、なんとか求められる式がでてきてACできた。

 公式解説を読むと、あっさりもっと簡単な形に変形していた。とはいえ、こういうのはどうやって思いつけば良いのか。

2023年10月24日火曜日

AtCoder Heuristic Contest 025

  pretest186位→システムテスト188位。

コンテスト後のツイート

 Step3の山登り部分で、改善しているかを厳密に判定する方法があったことに気付かなかった。
 これが一番の反省点か? これを直せばかなり順位が上がるのか? と思い、ここだけ直してみたら、改善はしたものの10個くらいしか順位が上がらなかった。うーん、根本的にダメなところがあるんだなぁ。

キーエンスプログラミングコンテスト2023秋(AtCoder Beginner Contest 325)

 Fまで六完で黄色復帰。Fまでは結構速かったのに、一時間以上かけてもGが解けなかったのは反省。

コンテスト後のツイート

G - offence 

 解法ツイートなどを見てAC。

 区間DPと気付いたのは良かったのだが、

・DP[i][j]=区間[i, j)が消せるかどうか

 だと上手くいかない。
 ここで今、DP[i][j]を0/1で持っているが、もっと多くの情報を持たせれば良いのでは? と考えるべきだった。

・DP[i][j]=区間[i, j)が消せるかどうか、そして消せるならさらに何文字消せるか

 を持てば良い。そうすればDPが回る。

 自然な解法で解ける問題だった。

2023年10月15日日曜日

yukicoder contest 408

 一問も解けず。ひどい。


No.2500 Products in a Range

 解説AC。

 Aの要素を正負で分け、正と負でそれぞれ連続区間を取るのでは……などと考えていた。だが、色々な場合を考え損ねて迷走。
 特に、lとrを正負で分ける方針は思いついたのになぜか必要がないと結論してしまった。

 落ち着いて場合分けすれば解ける問題くらいはちゃんとやらないと。

No.2501 Maximum Inversion Number

 問題のタグだけ見てAC。

 全部の要素を同じくらいの個数にすると転倒数が大きくなりそう、と考えたら思いつけた。

2023年10月14日土曜日

Codeforces Round 903 (Div. 3)

 Eまで五完。Fが解けなかったのはまずい。


F. Minimum Maximum Distance

 解説ツイートなどを見てAC。

 コンテスト中は、「木ではなく一直線の場合は三分探索で良さそう。三分探索を木上に拡張できる方法はないか?」と考えて困っていた。
 そのせいで問題への考察を怠っていた気がする。

 今回は、印がついている頂点のうち考えるべきものが絞れることに気付かなくてはいけなかった。端の頂点しか考えなくて良い。
 「端」というのが何かというと、印がついている頂点たち(とその間の頂点)を結ぶ木を作ったとき、その直径になっている頂点だけ調べれば良いということ(というか、直径/2の切り上げが答えである)。
 言われてみれば当然に思えるのに、結構時間をかけても気付けなかった。



2023年10月9日月曜日

AtCoder Regular Contest 166

 Cまで三完。

コンテスト後のツイート

D - Interval Counts

 解説AC。

 コンテスト中は、最小値を取りたいということから、(-∞, ?]や[?, ∞)という区間をいっぱい作りたい……というところから考えてしまったが、この方針はあまり良くない。

 もっと根本的に、[L, R]という区間をいくつか張る問題だということを意識するべきだった。
 そうすると、Yの隣接差分を見ることで、区間が何個始まるか、何個終わるか、の差分が分かる。しかし、ある場所で区間が終わり、同時に始まったとすると、その二つはくっつけた方がいいのは当たり前。
 ということは、Yの隣接差分は、「各場所について区間が何個始まるか、もしくは何個終わるか」を表していることになる。そうすると、貪欲に(できるだけ昔始まった区間から)消費していった方が良いというのは自然。

2023年10月8日日曜日

Educational Codeforces Round 151 (Rated for Div. 2)

 Dまで四完。

コンテスト後のツイート

E. Boxes and Balls

 こたつがめさんの実況放送の振り返りを見てAC。

 コンテスト中、左端の1はどこからどこまで詰められるのだろう? などと考えていた。大まかな方針はそれで良いのだが、「どこからどこまで」ではなく、全てのnについて試さなくてはいけなかった。

 各i in [0, n)について、何番目のボールをそこに置くか? そうした場合の移動距離はいくつか? というDPを考えると三乗のDPになり、それを枝狩りすると通る。

 三乗DP自体は自然なものなので、それは思いつかなくてはいけなかった。

yukicoder contest 340

 A一完で終了。


No.1909 Detect from Substrings

 解説AC。

 最初の二つの文字列から答えを絞るのがポイントだが、そのためには、「答えが少なそう」と気付かなくてはいけない。
 絞れると分かった後の考察も結構難しいが、「異なる最初の文字」に注目して考えれば良い。

 分かってしまえば難問という程ではないのだが、問題の見た目がシンプルなのに、腰を落として考える必要があるのが難しい。

No.1910 High Element on Grid

 $R_i$、$C_i$が、「A[j]がA[:j+1]の最大値になっているようなjの個数」を表していることは分かったが、その構築をどうやるか?

 ……結構考えても分からず解説を見たが、あまりにも単純でびっくり。一行目一列目が特別だと気付いていなかった。

2023年10月7日土曜日

Pinely Round 2 (Div. 1 + Div. 2)

 pretestはEまで。

コンテスト後のツイート

F. Divide, XOR, and Conquer

 こたつがめさんの放送の振り返りを見てAC。
 いや以前に、この放送や公式解説を見たときは分からなくてしばらく放置していたのだけど、今もう一回きちんと見たら理解できた。

 区間DPでいけそう、と言われればそういう気はしてくる。(n=10000でも想定計算量が二乗の可能性があることに注意しよう)
 ただ、区間DPが二乗で済むと思いにくいし、また、空間計算量が線形で済むと気付きにくい。

 区間DPでいけると言われれば自然な解法に思えるが、それでいけるとは思いにくい問題な気がする。

・Sを累積xorとする。
・最上位bitに注目するのは自然。
・長さが長い区間から区間DPしていく。

・[l, r]でS[l]とS[r]の最上位bitが同じなら、[l, n], [n, r] for any n(ただし、それぞれの区間は元のものより短い)に遷移できる。

・[l, r]でS[l]とS[r]の最上位bitが異なるなら、そのbitをxとすると、[l, n]に遷移できるのは、S[l]^S[n]のx bit目が異なるとき([n, r]も同様)。これを覚えておきたいが、そのとき、「S[l]が左端になるときは、右端とx bit目が異なれば良い」とさえ覚えておけば良い。

・この後、xと異なるyについて、「S[l]が左端になるときは、右端とy bit目が異なれば良い」を覚えておきたい状況が存在するかもしれない。そのため、(1<<x)|(1<<y)と記録しておけばOK。



yukicoder contest 407

 Cまで三完。


No.2495 Three Sets

 コンテスト後自力AC。

 A, B, Cを大きい順にソートしておき、それぞれ何個取るべきかを三分探索で求めたらACできた。
 コンテスト中にこの方針は思いついたもののあまり自信がなくて実装せず、コンテスト後に実装したらAC。

No.2496 LCM between Permutations

 WAが出て、WAが出たtestcaseを見てデバッグしてAC。

 (1, i)を全て聞いてみる。
 それで、Bの中に1があるところを特定できれば簡単。そうでなければ特定できたもののうち最も大きい素数を考え、そのindex indを使って(i, ind)を聞く。

 そういう感じで、AかBかで特定されていない場所が二個以下になるまで聞く。
 そうしたら、片方が1と分かるので、それを利用する。

 ……みたいにしてACできたが、多分、Hackできますね。(多分できなそう。追記しました)

 解説を読むと、N/2より大きい素数の位置がN+1回あれば見つけられることを利用していた。そういう素数の位置が分かると良いことには気付いていたが、N回で見つけられなかったとき、もう一回で見つけられるとは気付いていなかった。なるほどです。

 (追記)
 自分の解法は正当な気がしてきた。N/2より大きい素数をpとして、(1, i)を全部聞いたとき、A[i]=pならばBは二要素以外全て明らかになる。それ以外だったら、Bの中のpが最大の素数になる。
 だから、正しそう。

No.2497 GCD of LCMs

 解説AC。

 一般グラフの単純パスたちの持つ性質を考えるという問題が、ダイクストラで解けるとは考えもつかず、結構びっくりした。

 とはいえ冷静に考え直すと、一般グラフのサイクルとかを扱うのは難しい(サイクル基底を使う、とかはあるけれどそういう問題ではなさそう)し、何か上手いことをして最短距離問題に持ち込むくらいしかないのかもしれない。

2023年10月5日木曜日

yukicoder contest 390

 Eまで。

コンテスト後のツイート

No.2319 Friends+

 解説AC。

 解説で、bitsetで解けると書いてあったので、その方法でAC。
 平方分割を使うのだろうと考えていて、実際それでも解けるのだが、bitsetを使えることも思いつけなくてはいけませんね。
 ただ、高速な言語ではbitsetで通せても、PyPyなら平方分割するしかない、という場面もあるのだから、平方分割でもちゃんと解けなくてはいけなかった。

 友人が多いか少ないかで場合分けするとは思ったけれど、その生かし方が分からなかった。そこは冷静に考えるしかないのだが。

2023年10月3日火曜日

yukicoder contest 391

 ABの二完。


No.2336 Do you like typical problems?

 自力ACしたが、非常に時間がかかってしまった。難しい問題ではないと思うが、大まかな方針が立った後、立式しても自分が何を求めているか分からなくなってしまう……。

 想定解とほぼ同じ方法だが、想定解でいもす法を使っている部分で、平面走査を使っている。
 TLEできつくなってしまったのはそのせいなのだろうか? 定数倍高速化を頑張ったらACできた。

No.2337 Equidistant

 解説AC。
 大体の方針は分かったが、LCAがちょうど間にあるケースを考え損ねていた。典型だけど、そのケースを見逃しやすい。

 ダブリングによるLCAを久しぶりに実装した。ライブラリに入れておこう。

2023年9月29日金曜日

Codeforces Round 899 (Div. 2)

 Cまで三完。

コンテスト後のツイート

D. Tree XOR

 解法ツイートを見た。コンテスト中はbitごとに全方位木DPする方法しか思いつかなかったが、bitごとにやらずにできる。

 辺ごとの寄与を考える。辺に両端の頂点のxorを書き込んでおくと、その両端の二頂点を一致させるためには、「その値*葉の方の頂点の個数」のコストがかかる。これを全方位木DPで求めればOK。(さらにいうと、全方位木DPもいらないらしい)

 bitごとにやろうとしたときの全方位木DPはなかなか書きにくかったが、こちらの全方位木DPは実装も素直でした。

2023年9月28日木曜日

Educational Codeforces Round 155 (Rated for Div. 2)

 Dまで四完。

コンテスト後のツイート

E. Interactive Game with Coloring

 解法ツイートを見た。
 高々三色で良いというのは良かったが、根から出ている枝ごとに、次の辺を1にするか2にすべきか調べなくてはいけなかった。

・子供が複数出ている頂点については、子供たちへの辺を同じ色にすれば良い。
・親が一つ、子供が一つの頂点は、三色で塗るなら、1→2→3→1……と次数順に塗っていけばいい。
 二色で塗るなら、子供が一つの頂点全てについて、親への辺が1、子供への辺が2になるようにする。それが可能なのかを調べる。

2023年9月26日火曜日

サントリープログラミングコンテスト2023(AtCoder Beginner Contest 321)

 Fまで六完だが遅かったりペナが多かったりで黄色に戻れず。Fは形式的ベキ級数を考えたのは良いのだけど、「注文の多い高橋商店」と同じ問題かと思ったらもっと簡単なDP(形式的ベキ級数で言うなら、簡単な式の掛け算、割り算)だったんですよね。もっと落ち着いてDPの式を考えないと。

コンテスト後のツイート

G - Electric Circuit

 解説放送を見てAC。$3^N$のbit DPだとは思ったが、正しい解法にたどりつけなかった。

 集合iに対して、DP[i]=iが連結成分になる場合の数と定義したとき、DP[i]を求めるところで何を引けばいいか分かっていなかった。

 まず、内部でいくつかの連結成分に分かれているかどうかは考慮せずにDPの値を求めておく。そこから$3^N$のbit DPを使って値を引いていく。

 $i=j\cup k$と表せるとき、DP[j]*DP[k](ではないが、そのようなもの)を引くわけだが、全ての部分集合に対してこれを引くと二重に引かれる部分が出てしまう。iに属するある頂点xを定め、xを含むようなjに対して、DP[j]*DP[i/j]……ではなく、DP[j]*(i/jが一つの連結成分になっていなくても良いが、その外との辺はないような場合の数)を引いていかなくてはいけない。

 (i/jが一つの連結成分になっていなくても良いが、その外との辺はないような場合の数)は、「引く前のDPの値」なので、既に求まっている。

 解法の大枠は分かっても、詰めるのは大変な問題でした。

 ただ、「同じものをダブルカウントしないため、「ある頂点を含むものだけ考える」などしなくてはいけない。」とは、この記事にも書いている。同じところで分からなくなったのは良くない。

2023年9月23日土曜日

Codeforces Round 898 (Div. 4)

 全完。あまり速くはなかったけど、普通に全完できて良かった。

コンテスト後のツイート



yukicoder contest 405 技術室奥プログラミングコンテスト#7 Day1

 A一完。


No.2480 Sequence Sum

 解説AC。

 全く思いつかなかった。
 1と2から作れる長さはいくつだろう(これは求められる)、そこからxとx+1で作れる個数も計算できないか? などと考えていた。

 こういう考え方ではなく、作れない長さはいくつだろう? と考えるべきだったんですね。

No.2481 Shiritori

 一応、自力AC。

 「aで終わってaで終わる単語」の個数を考えたら、先手が勝つ場合の勝つ方法は分かった。それ以外で後手必勝ということが分からなかったけど、投げてみたらAC。
 解説を読んだら、後手が勝つ方法も簡単(先手の場合とほぼ同じ)でした。

No.2482 Sandglasses

 解説AC。

 あまり考えずに解説を見てしまったが、有名問題の解法を使ってすっきり解ける問題だった。これは自力で解きたかった。

2023年9月22日金曜日

THIRD プログラミングコンテスト 2023 アルゴ(AtCoder Beginner Contest 318)

 Fまで六完。

コンテスト後のツイート

G - Typical Path Problem

 フローだという情報を得てAC。

 フローだと言われれば、解くのは難しくない(頂点数を倍にするところで引っかかったけど)し、フローにしか見えなくなる。
 けど、こういうグラフの問題をフローで解いた経験がなかったのでちょっとびっくりでした。

2023年9月21日木曜日

トヨタ自動車プログラミングコンテスト2023#5(AtCoder Beginner Contest 320)

 Fまで六完。

コンテスト後のツイート

G - Slot Strategy 2 (Hard)

 解説放送を見てAC。コンテスト中フローじゃないかとは思ったけど、二部マッチングに帰着できると気付いていなかったので何も惜しくなかった。

・各数字について考え、二分探索するとフロー(二部マッチング)になる。
・時刻の個数が問題だが、各リールについて高々N個だけ考えて良い。

 一つ目は思いつくべき内容で、それを思い付いていなかったのはいけない。二つ目は難しいが、計算量を落とそうと試行錯誤していれば思いつくかもしれない。

 なお、二分探索のNGをN-1と設定してWAをくらった。0秒後から始まるので、NG=N-2と設定しなくてはいけない。機械的にNG=-1とかしていれば問題ないが、下限を見積もろうとするとやってしまいやすいミスかと思う。

2023年9月20日水曜日

AtCoder Regular Contest 165

 Cまで三完だが、解くのが遅くペナルティをたくさん出したため青に落ちる。最近ケアレスミスが多い。

コンテスト後のツイート

D - Substring Comparison

 解説放送を見てAC。

 SCCを作る方針はあっていたが、一回のSCCでやる方針を考えていた。
 最初の文字から比較していくという方針は辞書順という条件を思えばとても自然(コンテスト中もまずはそれを考えたと思う)。ただ、何度もSCC作りを行って良いというのが思いつきにくいですね。

 

CodeTON Round 6 (Div. 1 + Div. 2, Rated, Prizes!)

 遅解き四完。前半で苦労したのが響きレート-115。Eを解けなかったのはまあまあ仕方ないが……。最近、序盤のミスが目立つなぁ。

コンテスト後のツイート

E. Another MEX Problem

 解法ツイートを見てAC。
 DPを考えたのだが、区間DPを考えたのが失敗。左から順に作っていけば良かった。その上で、考えるべき遷移の個数が抑えられることが難しい。

 DP。左から作っていったとき最速でその数字を作れるかを判定していけば良い。
 遷移に使う[l, r]は、[l, r]が最も短いものを選べば良い。この個数はO(n)個に抑えられる。

 

2023年9月16日土曜日

yukicoder contest 404

 ABの二完。


No.2462 七人カノン

 解説AC。全然思いつかなかった……。

・ある時刻に何人演奏しているか? はimos法を使えば求まる。
・それ(の累積和)を使えば、各クエリについて目立ち度の増加分が求まる。

 言われてみれば簡単。

 一気に考えようとせずに、「何人演奏しているか?」と「目立ち度の計算」を別々に求めようと考えなくてはいけませんでした。

No.2463 ストレートフラッシュ

 解説AC。

 何かしらのDPだろうと考えたが違っていた。制約から考えても、ストレートフラッシュの種類を決め打つのは自然。思いつかなくてはいけないなぁ。

2023年9月15日金曜日

AtCoder Beginner Contest 319

 Eまで五完。黄色に戻れず悲しい。
 Gは大量ペナを出したが22:40ちょうどに通った。あと一秒早ければ黄色に戻れたのに……。


F - Fighter Takahashi 

 bit DPだという解法ツイートを(たまたま)見てAC。

 bit DPだと分かれば特に難しいところはない。ただ、実装は大変。

G - Counting Shortest Paths

 コンテスト中考えていた(そして、22:40ちょうどにACした)解法は嘘解法だと思ったが、改めて考えるとそうでもないのかも?

 Nが小さい場合は普通にやらうとして、Nが大きい場合。

 startとgoalからBFSしていくと、それぞれstartからi歩でいける頂点Q、goalからj歩でいける頂点Q2が得られる。len(Q)*len(Q2)がMより大きいとき、必ずそこは一歩でいけるので、len(Q)*len(Q2)から、「Q中の頂点からQ2中の頂点へ辺が引かれているもの」を引けば良い。

 これで上手くいかないのは、ちゃんとDPしなくてはいけない場合、つまり、ある頂点を通る最短経路が二つ以上存在する場合だけれど、そういうのはNが小さい場合でないと起こらないんじゃないだろうか?

 ちゃんと考えるとよく分からなくなってきた。やはり正しい解法で解きましょう。

2023年9月3日日曜日

yukicoder contest 403

 ABDの三完。


No.2452 Incline

 hiro1729さんの解説を見てAC。
 floor sumが必要になりそうなことは分かり、「A(傾き)が負だった場合の式」の導出まではできていたのだがそこからどうすれば良いか分からなかった。

 この解説を読むと、floor sumのライブラリを少しいじるだけでAが負の場合にも対応できることが分かる。実際そう直したらACできた。

 なぜそれで良いのか分からなかったが、改めてkyopro_friendsさんのfloor sumの解説を読んだらこれで良いことが理解できた。

 公式解説はfloor sumを使っていないようですが、それはそれで難しい。

No.2454 Former < Latter

 suffix arrayを使おうとしたが上手くいかず失敗。Z algorithmを使うという情報を得てAC。

 文字列アルゴリズムの内容はちゃんと把握しておかなくてはまずい。

2023年9月2日土曜日

Educational Codeforces Round 154 (Rated for Div. 2)

 Dまで。

コンテスト後のツイート

E. Non-Intersecting Subpermutations

 解法ツイートを見てAC。解けなくてはいけない難易度だった。

 結構シンプルなDPだった。今の文字までの連続部分列を見たとき、最大何個重複しない数字を取れるか? を持てば良い。
 一応、累積和が必要になるけど難しくない。

2023年9月1日金曜日

第四回日本最強プログラマー学生選手権-予選-(AtCoder Beginner Contest 313)

 Eまで五完。

コンテスト後のツイート

F - Flip Machines

 解説を読み、bit DPのところが分からず解説放送を見てAC。

 X_jとY_jが異なるようなマシンを起動すると、それらのカードにおいて期待値は表裏の平均になる……というのは言われれば分かるがパッと思いつくのは難しい。

 だが、その後の方がもっと難しい。マシーン全探索で答えが求まるのは分かるが、それでは計算量が無理。
 Nが40以下というのを利用するだろうと予想できるが、「裏が表より大きいもの」と「裏が表より小さいもの」と分けて、

・「裏が表より小さいもの」につながるいくつかのマシーンを起動したとき、いくら儲かるか? を考えると貪欲に取れる

 ということにまず気付かなくてはいけない。これで、「裏が表より小さいもの」がNの半分より少ないときは間に合う。

 あとは、「裏が表より大きいもの」が少ないときを考えれば良い。(と、二つに分けて考えるのがまず難しいのだが)

 こちらの場合は、bit DPを使う。「裏が表より大きいもの」の集合Sを考え、そのときの損の最小値はいくらか? というのをDP[S]でもつ。そのDPテーブルを、「裏が表より小さいもの」一つずつを見て更新していけば良い。


 解説を見て理解する分には難しくないのだが、実際に解くのは大変に感じる。

G - Redistribution of Piles

 自力AC。

 できることが、何回か減らしてから増やす、しかないので、ある減らした状態から何回増やせるかを考えれば良い。
 そうするとfloor sumを使いそうな式になるので、この公式(?)が使える形に変形するとACできた。

 ただ、自力ACとは書いたけど、最近のコンテストでfloor sumを使う問題が出たという記憶に残っていたから解けただけかもしれない……。

2023年8月29日火曜日

Harbour.Space Scholarship Contest 2023-2024 (Div. 1 + Div. 2)

 Eまで五完。

コンテスト後のツイート

F. Exotic Queries

 Mo’s algorithmを使うのかと思ったが、違っていてびっくりした。これっぽい、と思った解法が違っていることは少ないので。

 解説AC。

 えー、解法を理解するのも、それを平面走査に持ち込むところも非常に苦しんだ。

 a=A[i]となる隣接するindexがxとyだった(つまり、A[x]=a, A[y]=aで(x, y)にA[i]=aとなるものはない)とき、xとyの間に、aより小さいものがあれば答えが一つ増える、というのが発想の元なのは分かるが、ここまで分かってもどう定式化すれば良いかが難しい。

 その後、この問題が平面走査で解けるということを理解するのも難しかった。

 典型の組み合わせだということは分かるが、あまりコンテスト中に解けるビジョンが見えない……。

 また、PyPyだとTLEが取れず、chatGPTを利用してC++に直してACした。

 

2023年8月28日月曜日

ゲームフリーク Programming Contest 2023(AtCoder Beginner Contest 317)

 Eまで五完。 

コンテスト後のツイート


F - Nim

 桁DPだという情報を得てAC。

 何か数学的に上手い方法があるのではと考えてしまったが、

・xorの計算でそんなに上手い方法があることは少ない
・xorの計算なら桁ごとに考えるのが定石

 といったあたりを踏まえれば桁DPを考えるのは自然だった。
 桁DPと分かれば解法はすぐに思いついたこともあり、これを考えられなかったのは反省。なお、実装でバグを埋め込み修正にかなりの時間がかかってしまったけど、これは仕方ないかなぁ。

G - Rearranging

 この問題の解説を参考にしてAC。

 コンテスト中、この問題にはたどりつけていたので、焼きなましをしようなどと思わず真面目にフローで解こうとしていればACはできていたと思う。

 自力で思いついていないというのは身に着いていないということではあるのだけど、まずは類題に気付けるのが重要だと思っているので。

yukicoder contest 402

 AB二完だが、Bは乱択で通しておりひどい。線形代数の復習と思ってC以降も通したい。


No.2442 線形写像

 基底を考えれば良かった。
 1, 2, 4, 8,……の値を考えて、それと整合するかを調べれば良い。

 この解法は言われてみれば当たり前に思えるのに、全く思いつかなかったね……。

No.2443 特殊線形群の標準表現

 自力AC。
 ちゃんと問題文を読めば何も難しくない。累積積を取るだけの問題。

 ただ、決して難しい問題文ではないのだが、この量の数学的な文章を読むのは結構大変。そういう意味で数学的な能力が問われていると思う。
 特殊線形群ってなんだっけ? などと考え出すと問題文が頭に入ってこなくなる。ちなみに今回は、逆行列が簡単に求まるように、行列式を1にしただけなんですね。


No.2444 一次変換と体積

 解説AC。

 行列式が(二次元なら)平方四辺形の面積になるということを知らなかった(か、忘れていた)。解説でもその部分の詳細に触れていなかったけれど、検索したらたくさんでてきて知らなきゃいけないことだったのか、となった。

No.2445 奇行列式

 検索したら転倒数の偶奇と偶置換/奇置換が一致すると見てAC。
 この事実(定義として採用されることもあるみたい)も忘れていたが、自然な性質なので覚えておきたい。

 公式解説の方法はよく分かっていません……。

2023年8月26日土曜日

Codeforces Round 894 (Div. 3)

 全完だと思ったが、Fがシステムテストで落ちた。

コンテスト後のツイート

F. Magic Will Save the World

 bitsetで実装したのだが、DPの添え字が一つずれていた。なんでこれでpretestをACするんだろう……。

 0桁目は「0」を表すので桁が一つずれる。
 五個目までの有無を調べたいなら、(1<<6)-1をかけなくてはいけないし、k.bit_length() -1が取れる最大個数になる。





 

2023年8月23日水曜日

Codeforces Round 892 (Div. 2)

 Dまで四完。

コンテスト後のツイート

E. Maximum Monogonosity

 解説AC。
 絶対値を外すDPらしいと聞いたのに理解できず、けんちょんさんのブログを見てAC。

 分かってしまえば難しくないのだが……。
 とりあえず、絶対値を外すと聞いたのに絶対値をmaxに変える変形ができなかったのは反省。
 この問題のように、

・|A|=max(A, -A)

 を用いて絶対値を外すだけで道が開ける問題は結構ある(たとえば、この問題を思い出した)。とりあえず絶対値は外して、maxの式にして考えるくらいの気持ちで良いかもしれない。

2023年8月22日火曜日

Codeforces Round 893 (Div. 2)

 Cまで。


D. Trees and Segments

 こたつがめさんの実況放送の振り返りを見てAC。

 結構難問だと思う。

・ある場所で切って、それより左で0の連続区間、右で1の連続区間を作ろう

 と考えるのが難しい。

 その後は、計算量を考えずに答えを求めると、計算量削減部分は累積maxを取るだけなので解法で迷うところはない。
 ただ、結構変数が多く処理も多いため、整理して考えるのが難しい。

2023年8月21日月曜日

キーエンスプログラミングコンテスト2023夏(AtCoder Beginner Contest 315)

 Fまで六完。

コンテスト後のツイート

G - Ai + Bj + Ck = X (1 <= i, j, k <= N)

 自力AC。コンテスト中考えていた方針であっていた。

 拡張ユークリッドの互除法で各iについてB*j+C*k=X-A*iとなる(j, k)を一組求めた後は、j, kの増減がそれぞれいくつになるか考え、j, kが1~Nの範囲にあるという条件を丁寧に考えるだけである。
 そう思っても実際に実装するのは非常に大変だった。こういうのは紙に書いてからやった方が良いのかなぁ(普段はpaintでお絵描きしています)。ただ、計算が必要なわけでもないし、紙に書くほどのものでもない気もするんだよね。

2023年8月13日日曜日

AtCoder Beginner Contest 314

 Fまで六完。

コンテスト後のツイート


G - Amulets

 解説放送を見てAC。

 コンテスト中に、i番目までのモンスターまで倒すことを考えるなら、アミュレットは各タイプに関する攻撃力の和が大きいものから選べば良いことは分かっていた。なので、各Kに対してNを二分探索するTLE解法は思いついていた。

 そこまでいけば、後は差分計算するしかないはずなのだが、なぜ思いつかなかったのか。Kそれぞれの場合について求めるというのも差分計算を示唆する書き方である。

 Kではなく、モンスターの数で差分計算するという部分にちょっとした発想は必要だけど、(分かってしまえば)そこまで難しい発想とは思えないのだけど……。

 なお、実装にも苦労した。

 こうやってsortedcontainersを使ったので、手元でもsortedcontainersを使えるようにした。

 

2023年8月12日土曜日

yukicoder contest 401

 Dまで四完。


No.2411 Reverse Directions

 解説AC。

 考察要素より実装要素の方が難しい問題なのに、考察もできていなかったことを反省。

 どこかで行ったり来たりして時間をつぶすのだろうなぁ、とは思ったのに、反転する部分でそうするのが最適だと分からなかった。

 それが分かったなら、時間をつぶせる場所まで行けるか? そこで時間をつぶせるか? を調べれば良いが、実際に条件を書こうとすると結構複雑で、解説を読んだ後なのにWAを出してしまった。

No.2412 YOU Grow Bigger!

 タグの「全探索」を見て解法が分かった。
 何を全探索するのだろう、と思ったら答えが2以下になると気付けた。

 ただ、実装したらWAが出て、問題文を読み直したら、上下左右だけでなく斜めも動けることに気付いた。

2023年8月9日水曜日

Codeforces Round 891 (Div. 3)

 全完。Eでやや苦労した以外は順調だったと思うのだけど、それほど良い順位じゃないのは、うーん。

コンテスト後のツイート

 EとFでdictやCounterを使いたくなり、Hack対策をするのが面倒くさかった。

2023年8月7日月曜日

Codeforces Round 890 (Div. 2) supported by Constructor Institute

 A, B, E1の三完。Cが解けなかった!

コンテスト後のツイート

C. To Become Max

 解説AC。

 最初、二乗が通らない制約だと勘違いしていて、途中で二乗が通ると気付き、足す区間[l, r]の全探索を考えていた。
 が、これは筋が悪い。累積和との差分を使ったりすればコストが求まる気がしていたが、途中で膨らんだりした部分があるとコスト計算が正しくなくなる。このことにコンテスト中は気付いていなかった。

 あるindexをmまで上げるのに必要なコストは? と考えて、このmを二分探索で解くのが正しい解法だった。これもそれぞれO(n)かかるので、二乗+二分探索のlogで解ける。

2023年8月5日土曜日

yukicoder contest 400

 Dまで四完。

コンテスト後のツイート

No.2403 "Eight" Bridges of Königsberg

 解説AC。

 (入次数)-(出次数)が影響するのは分かったが、連結成分数がどう関わってくるのか分からなかった。

 これ、分からなかった原因は、上手い例を構築できなかったせいだとおもう。

 極端な例を作ろうとして、入次数が出次数よりとても多い(または少ない)グラフばかりを想像して、入次数と出次数が同じグラフを考えなかったのがまずい。
 イコールというのも極端な場合ですね。これを考えなくてはいけなかった。

2023年8月4日金曜日

Codeforces Round 881 (Div. 3)

 Eまで五完。


F1. Omsk Metro (simple version)

 こたつがめさんの実況放送の振り返りを見てAC。

 実装はしなかったけど、当時F1の解法は分かっていた気がして、それを思い出すために見たつもりだったのだけど、こういう思考をした覚えがないから間違えていたのかもしれない。

 どちらかというとF2のために見て、解法は理解したのだけど、F2はPyPyだと通らなそうなので一旦放置します。

2023年8月3日木曜日

Educational Codeforces Round 152 (Rated for Div. 2)

 Dまで。

コンテスト後のツイート

E. Max to the Right of Min


 まとめると、

・(l, r)のlを固定
・lを固定したとき、l以降の累積max、累積minを取っていれば、rから左へ見ていったとき累積maxのindexが累積minのindexより先に現れたらその(l, r)が条件を満たす。
・累積maxや累積minの差分更新はstackを使ってできる。

 あとは二分探索を使って実装した。(こたつがめさんは遅延セグ木といっていたけど、二分探索の方が自分には分かりやすかったので)


 考える方針としては、lを固定するか、最小値を固定するか、くらいしかなさそうなので、lを固定することは考えたはずなのだけど、累積maxや累積minさえ分かれば良いということにも気付いていなかった。
 それは、ちゃんと図を描いて考えましょう、くらいしか言えなそう。どういうrが条件を満たすのかよく図を見て考えるしかなさそうですね。

2023年8月2日水曜日

Codeforces Round 889 (Div. 1)

 A1とCの二完。

コンテスト後のツイート

B. Earn or Unlock

 bitsetを使うと解けるらしいという情報を得てAC。

・問題が部分和問題に似ているので、DPするしかなさそう。
・(コンテスト中は)PyPyによるACがなく、C++でも実行時間が長いものが多い

 ということから、コンテスト中もbitsetの利用は疑ったはずなのだが、良い方法が思いつかなかった。


 実際は、部分和問題のときと同じ要領でDPテーブルを持てば解ける。
 DP[i]=1で、ちょうどindex iまで使える状態、ということを表すとすると、

・初期状態はDP[0]=1、他は0
・DP[i]=1のとき、iまでの累積和-iが答えの候補。
・DP[i]=1のとき、index i以降で1となっているものについて、DP[i+A[i]]=1と遷移させれば良い。これは、DP>>=i, DP|=(DP<<A[i]), DP<<=iのように表せる。

 となり、解ける。

 なお、現在はPyPyでのACもあるが、bitsetを書くのが簡単そうだったので久しぶりにC++を使ってみたら、昔ほど書くのに抵抗ない気がした。VSCODEを使ったら、いつのまにかボタン一つで実行できるようになっていたのも嬉しい(前はできなかったのに、なぜ?)。


2023年8月1日火曜日

AtCoder Grand Contest 063

 AB二完。

コンテスト後のツイート

C - Add Mod Operations

 解説AC。

・差に注目すべき。各差が一致するように移していけば良さそう
・大きい数個を小さい方に移せる

 ということには気付いていたのに、最大値一個を0にすることで差を調整していくことができると気付いていなかった。
 random解を生成してしまったせいもあるのかな……。ソートしてから考えることができるとは気付いていたので、せめてソートした後でrandomを試すべきだったかもしれない。

 なお、引っ掛かったというツイートをいくつか見ていたにもかかわらず、x<yを満たさない出力をしてWAを出したのは反省。

2023年7月30日日曜日

ユニークビジョンプログラミングコンテスト2023 夏 (AtCoder Beginner Contest 312)

 ABCDFGの六完。

コンテスト後のツイート

E - Tangency of Cuboids

 100*100*100の小立方体に分けて考えれば良いという解法ツイートを見てAC。

 コンテスト中は、ある断面で切って区間スケジューリング問題みたいに解く方針を考えていたが、それだと辺のみが共有する場合がうまく処理できなくて困ってしまった。
 こういう方針でも解けるらしいけど、どうやるんだろう……。
 


2023年7月29日土曜日

Codeforces Round 887 (Div. 1)

 Bまで二完。Aがすぐ分からなかったが、Bを解いた後戻って考えたら分かった。

コンテスト後のツイート

C. Ina of the Mountain

 解説AC。解法ツイートでpriority queueを使うなどと言われても分からなかったが、公式Editorialが丁寧だった。

 (A[i]=kのものはA[i]=0に前処理した上で、)

・A[i]かA[i]+kのどちらかを使うと思って良い。
・登りのときだけコストがかかると考える。そうすると、次の戦略が最適:下りはとりあえず下っておくとする。下りを後で登りに変更することを考えると、-xの下りを登りに変更した場合、k-xのコストがかかることが分かる。なので、登るとき、「今までの下りのうちのどれかを登りに変更するか、ここを登るか」これらのうちの最小値を選べばよい。(ここでpriority queueを使う)

yukicoder contest 399

 ABの二完。Cを考えているときに体調が悪くなり撤退。

No.2394 部分和乗総和

 自力AC。

 しばらく分からなかったが、形式的ベキ級数に思いを馳せたら解けた。

No.2395 区間二次変換一点取得

 自力AC。

 各indexごと独立なので、各indexについて何回クエリが適応されているかだけ見れば良い。
 問題文を理解するのがちょっと難しいけど、理解してしまえばBやCより簡単では。

2023年7月28日金曜日

Codeforces Round 888 (Div. 3)

 Gが解けなかった。

コンテスト後のツイート

G. Vlad and the Mountains

 並列二分探索を使わないでも解けるというツイートを見てAC。

 しばらく考えて分からなかったのが、並列二分探索で解けるということに気付いて喜んで実装したらMLEやTLEが出て、残り時間が少なかったため定数倍高速化を試したがACできなかった。

 落ち着いて考えれば、「start時点の山の高さ+e」までの高さの山を結んだときstartからgoalにたどりつけるかさえ調べればよいため、並列二分探索は必要なかった。

2023年7月23日日曜日

トヨタ自動車プログラミングコンテスト2023#4(AtCoder Beginner Contest 311)

 Fまで。

コンテスト後のツイート

G - One More Grid Task

 解説AC。

 「最大長方形」のアルゴリズムを使うのかな、とはコンテスト中に考えたのに、(検索したら)最大長方形のアルゴリズムはヒストグラムの形にしか適応できないことを見て、この問題には適応できないと思ってしまった。
 「i行より上の部分だけを見る」として最大長方形のアルゴリズムを適応する発想がなかった。

 最大長方形のアルゴリズムを使うかもしれないと思ったのなら、もうちょっと使える形に変形できないか考えないと。

Codeforces Round 886 (Div. 4)

 pretestは全完。あまり迷うところもなかったので、GがHackされ、FでシステムテストでTLEしていて驚いた。

コンテスト後のツイート

F. We Were Both Children

 Pythonでset(Counter)を使うとHashを衝突させられる案件でTLEしていた。
 何の気なしに、Counter(A)と書いてしまった。
 Counter(sorted(A))に直してAC。

G. The Morning Star

 これもF同様Counterのせいで落ちていた。
 ただ、sortしただけでは通らないケースが入っており、座標を1ずらしたらACした。

 CodeforcesではsetやCounterを気楽に使ってはいけないってことですね。うーむ。



2023年7月22日土曜日

yukicoder contest 398

 ABの二完。


No.2387 Yokan Factory

 自力AC。

 答え二分探索+ダイクストラ。解法は分かったのに睡魔に襲われて実装できなかった。しかし、いくら眠くてもこれを実装し切れないのはですね。

No.2390 Udon Coupon (Hard)

 自力AC。

 最も効率良いものをたくさん買った後、残りをDPすれば良い……というのは、この問題などを解いていたため知っていた。
 それなのに、三分探索で良いのでは? などと混乱してしまいWAを出したのはダメ。

2023年7月18日火曜日

freee プログラミングコンテスト2023(AtCoder Beginner Contest 310)

 Fまで六完。

コンテスト後のツイート

G - Takahashi And Pass-The-Ball Game

 解説を読んだけど、ダブリングの解法がすぐには理解できず、解説放送も参考にしてAC。

 ダブリングでいけそうということは分かっても、実装するのが難しい問題だった。
 ダブリングでさくっと求められるのは、「xさんのボールがy回の操作後どこにあるか?」だが、ダブリングの途中で二回の操作を一回にまとめていかねばならないため混乱しやすい。

 ダブリングをこういう風に使ったことがなかった気がするので、ちょっと新鮮だった。

 コンテスト中は行列累乗なんかを考えたりしていて的外れでした。

Ex - Negative Cost

 解説放送を見てAC。

・ナップザック問題で重みが大きいときどうするか?

 という問題の解法を知っていないと解くのが厳しかったと思う。
 最大効率に着目するのは直感にも合致していて、確かにそうだな、という感じ。

 この問題に帰着しようと思えたのなら、帰着する部分は思いつけなくはなさそう。


Codeforces Round 885 (Div. 2)

 BCDの三完。

コンテスト後のツイート

A. Vika and Her Friends

 解法ツイートを見てAC。

 市松模様に分けたとき、自分と同じ場所に来る可能性があるのは、同じ色の場所のみ。
 自分が動いた後、敵は自分の動きを見てから移動できるので、敵が同じ色の場所に一人でもいたら捕まる。

 読解がやや難しくて、最初問題を読んだときは勘違いした(一手後に捕まるかを判定するのかと思った&「敵は自分の動きを見てから移動できる」を読めていなかった)が、最後は正しく理解していたのに分からなかった。
 「敵は自分の動きを見てから移動できる」というのを正しく読めたのに解法に反映させておらず、よく分からないけど敵が二人いたらダメなのかな、などと考えていた。

 コンテスト中の立ち回りとしては、すぐに理解できなかったら飛ばすのが正解だったと思う。飛ばすのがちょっと遅かった気はするけど、まあ良いか。

2023年7月15日土曜日

yukicoder contest 397(群論コンテスト)

 ABDの三完。

No.2381 Gift Exchange Party

 解説AC。

 こういう問題で、iからA[i]に辺を張ったグラフを考えるのは典型。Pが素数なので、そのグラフにおけるサイクルが全て1かPになれば良い。

 コンテスト中は、Pが素数だということを読み飛ばしていた。が、このグラフすら考えていなかったのは反省。サイクルが~みたいなことをぼんやりと考えていたはずだが、何を考えていたのだろう……。

 また、実装はTester解説の方法でやったが、累積積による高速化が必要なことに気付かなかったりして手間取った。
 DPでやるのが簡単なのですね。今まで使っていない最も小さな数に注目するのが良いのか。それならPが素数じゃなくても解ける。形式的ベキ級数でも扱えるらしい。

No.2383 Naphthol

 バーンサイドの公式について、高校数学の美しい物語を参考にしながらAC。

 modを取っているのに、(*pow(4,mod-2,mod)とせず)4で割っていて答えが合わず困ったのは恥ずかしい。
 

2023年7月3日月曜日

AtCoder Regular Contest 163

 AB二完。

コンテスト後のツイート

C - Harmonic Mean

 解説AC。

 部分分数分解を利用するというのを見て実装しようとしたら、全体二倍にするというのを思いつかず苦戦してしまった。

 部分分数分解を利用する方針は全く思いつかなかったので解けなくても仕方なかった……とも思うが、他の方針で(やや強引に)通している人も結構いる模様。それを見るとどうにかして通したかったという気持ちになるが、どうすれば良かったかね。

 コンテスト中は、和が1になるものx個を使って、それらをx倍したものを合併させる。もしくは、3個を2, 3, 6倍したものを合併させる……というような方針を考えていたが、Nが100~150あたりまでしか作れなかった。

D - Sum of SCC

 解説AC。

 問題を見て、主客転倒的なテクニックを使いそう、とは思ったが、グラフを二つに分けて考えるという発想はなかなか難しい。
 SCCをs0→s1→s2→……のように表してみて、この矢印をどこで区切れば良いか? と考えれば思いつけるのかなぁ。

 また、解説通りのDPをしたつもりが答えが合わずに苦労した。

 解説の一行目の「以下の値-1に等しいです」というのは、A側が空の場合とB側が空の場合をダブルカウントしているため、ということなのですね。
 これを踏まえて、最終的な答えを求めるときも、i(解説のdp内の添え字)の範囲を[0, N)もしくは(0,N]にしなくてはいけなかった。


 が、今回の問題の解法に引っ張られて二乗のDPで解く方法しか思いつかず、oeisを使ってなんとかAC、としてしまった。
 解説(のコード)を見ると、簡単に立式できましたね……。

2023年7月1日土曜日

yukicoder contest 395

 ABの二完。


No.2366 登校

 解説AC。

 ダイクストラを使いそうなのは分かるので、どういうダイクストラを使ってどうすれば計算量を減らせるか考える問題。

 疲労度の最小値を求める問題なので、

・DP[座標][時間]=疲労度の最小値

 とするのは自然。ただ、これだと時間をどの範囲で取ればいいか分からないのだけれど、どの地点からもN+M-2歩以内で行けることから時間を絞れる、という考察が必要でした。

 こう書くと自然な考察で解けるので、解きたかったね……。

 そして、解説を読み直しながらこの文章を書いていたら、実装ミスしていたことに気付いたので、再提出&自分のコードにChallengeにしておいた。
 時間を巻き戻すとき、昔過ぎる時間に巻き戻る遷移を禁じた実装をしていました。


2023年6月28日水曜日

Codeforces Round 880 (Div. 1)

 A一完のみ。

コンテスト後のツイート

B. Lottery

 こたつがめさんの実況放送を見てどうにか理解した。

 この解法に思い至れなかった要因は、当たりの位置をずらすことを考えていて、「何番目を買うとしたら当たりくじの位置はどこからどこまでか?」という考え方を全くしなかったこと。その後の考察も難しいけど、少なくともこれはどちらも考えてみるべきだった。

 PyPyだとTLEしたためRUSTに直したが、そこでも苦戦した。特に、

・RUSTのbinary_searchで、その要素が複数個入っていたときは、そのうちどのindexをわたすか分からない(多分。自分で実験した限りはそうだった)

 というのを知らなかったため原因に気付かず大変だった。今度RUSTで二分探索を使うときは気を付けよう。

C. Twin Clusters

 こたつがめさんの実況放送で理解。ただ、実装は乱択で通した。

 区間xorの値が同じになるのが二つあれば、それを使って答えが作れるのだろう……とは思っていたが、0が一つだけある場合はそれを除いて考えて良いということが分かっていなかった。そうすると、端点が同じ([l, r]、[l2, r2]でl=l2の場合)な場合に答えが作れるということも。
 これを思い付いていれば、乱択しようと思えたかな……。

 乱択じゃない解法については、鳩ノ巣原理を利用したいという気持ちを強く持てば下半分と上半分の桁で分けようと思えるのかな、と感じた。
 ただ、この鳩ノ巣原理はかなり余裕があるからできているわけで、それなら乱択で通るよね、という気持ちになった。


2023年6月26日月曜日

TOYOTA Programming Contest 2023 Summer(AtCoder Heuristic Contest 021)

 最終順位319位で、予選通過はダメでした。(ツイッターで317位と書いてしまったけどまだジャッジ中だったみたい)

コンテスト後のツイート


 解法は、ツイートの通りで、

・大きい順に、経路のコスト(置きたい段との差をコスト)を求めるDPをしてコストが小さいものを採用、としました。

 ただ、これは勘違いしていたせいです。ツイートを見ていたら同じ勘違いをしていた人が何人かいたけど、

・各数字が、0,1,2,..と並べたときと同じ段にならなくてはいけない

 と勘違いしていました。それで最初言ったような解法になってしまった。


 アルゴリズムの問題でもそうだけど、誤読とか、勘違いとかを一度してしまうと修正するのは難しい。
 今回は、最初に「適当に上下で値が入れ替わっていたら交換しまくる」というのを提出しているので、それでOKだったことを振り返る余裕があれば気付けたはずなのだけども……。まあそんな余裕はなかった。


 ただ、この勘違いがなくても、上手くできたかどうか。

 今回は、「13426585点が取れる貪欲アルゴリズム」を思い付けるかどうかが鍵だったが、これで上手くいくというのはそれほど明らかじゃない気がした。
 さらに、その改善ともなると、うーん。Kiri8128さんの解説の評価関数も全く思いつかなかった。これを実装したら確かに改善したけど、自分で思いつけたかというと……。

 ただ、コンテスト中、順位表で上位に同じ点数の人がたくさんいるのは見て、「何か簡単な解法があるはず」とは気付いていたのだから、とにかく色々な貪欲を試してみるべきだった、とは思う。

・小さい数字から試す
・上の二つのうち大きい方と交換

 というの自体は両方とも考えたことはあったのだから。

 それで自分の点数より伸びるとは思わなかった(ことと、勘違いしていた)から試さなかったのだけれど、それでも実装してみて、他にどんな解法やパラメータがあるか探らなくてはいけなかったのだろう。

東京海上日動プログラミングコンテスト2023(AtCoder Beginner Contest 307)

 Eまで五完。

コンテスト後のツイート

F - Virus 2

 解説AC。

 (感染した日, 感染した場所からの最短距離)を持つダイクストラでやった。これだと、「l日以降でx以上の数字がXに表れる一番最近のindexはどこ?」に答える必要があったので、セグ木二分探索を使った(使わなくてもできるらしいが、よく分からず……)。

 ダイクストラすることは明らかで、どんな解法でもできそうに思えるけど、実際に実装しようとするとつまる……みたいな問題だと思う。
 多分、解説見なくてもごちゃごちゃやっていれば解けたと思うけど、素早くこなすためにはどうすれば良いのかね。

G - Approximate Equalization

 解法ツイートを見るとツイートで書いた内容で大体あってそうで、

・x+1にした個数をもってDP

 だけ持てば良かった。

 それだと次の数字が何か分からない(一意に定まらない)気がしてしまったが、累積和を取っておけば、そこまでで使ったxやx+1の個数が分かっているため、差分計算で求まり、一意に定まる。
 制約を見ても二乗DPできそうなので、ツイートした内容のところまでいけば、正しい解法に至ることはできそうなのにねぇ。うーん。

 なお、解法が分かったつもりで実装しようとしたら、再度、「やっぱり次の数字は分からないのでは?」と思ってもう一度再考してしまったし、その上、一番最後にx+1を使う場合を考え損ねてWAを出したりした。

 解けなきゃいけない問題だったと思うのに、この様はまずい……。

2023年6月24日土曜日

yukicoder contest 394

 AB二完。

コンテスト後のツイート

No.2359 A in S ?

 解説は見たけど自力(?)AC。

 コンテスト中、「X, Yの条件がなければimos法だなぁ」と思い、XとYの条件があっても、それらをまとめて計算すれば計算量が落ちるのかも? と思ってheapqを使って(小さい(index, X)から処理するためにheapqを使った)書いたがTLE。heapqを使わずに書けそうなので、そこからlogは落とせると思ったが、計算量に自信がなかった(のと、BでRUSTに直してACしたので、この問題もRUSTに書き直そうか迷っていた)ため書き直さなかった。

 解説を見たら、それで実際計算量が落ちると書いてあったので、書き直してACしました。

2023年6月19日月曜日

トヨタ自動車プログラミングコンテスト2023#3(AtCoder Beginner Contest 306)

 Fまで六完。ジャッジが詰まったためGを解けなかったけれど、時間あったら解けてたっぽい。

コンテスト後のツイート

G - Return to 1

 コンテスト中に書いたのでほぼ合っていて、コンテスト中DFSで書いたもの(1caseだけTLE)をBFSに直したら通った。
 ジャッジが詰まっていたせいもあって適当に書いてしまったけど、BFSじゃないとTLEするのは当たり前でした。
 

2023年6月17日土曜日

yukicoder contest 393

 Dまで四完。


No.2354 Poor Sight in Winter

 一応自力でAC。

 二分探索+ダイクストラでいけるんじゃないか? とは問題を見てすぐ思った。

 ただ、a→bのルートに明かりを配置したとき、同時に別のc→dというルートがいけるようになることがある。だから、正当性が怪しい気がして実装せず考え込んでしまった。

 コンテスト後、「とはいえ、a→bのルートに明かりをx個配置したとき同時にa→cもいけるようになったとしたら、a→cもx個でいけるようになるな」と思い、やや正当性に自信が持てなかったものの実装したら(REやTLEを経て)ACした。

 なお、解説を見ると「明らかに,同じ明かりを二度使うことは最適ではありません.同じ明かりを二度使う場合,1 回目に使用してから 2 回目に使用するまでの間を省略できるからです」と書いており、それはそうか、となった。

No.2355 Unhappy Back Dance

 自力AC。

 角度が同じものを列挙すれば良いとは思ったが、三乗かかる気がして悩んだ。
 ただ冷静になると、それほど工夫は必要なく、「一点を固定し他の全ての点に対して角度を求めたものをdictに入れておく」で二乗でいけた。

No.2356 Back Door Tour in Four Seasons

 ちらっと解説を見たけど大体自力でAC。

 扉の順番を決めれば、そう進むときの場合の数は求められる。それを使って総和を求めるという方針。
 解説ではΣ計算を使っているけれど、DPの気持ちで考えた。

・DP[扉]=その扉に至るときの場合の数(それが夏の扉なら、どこかの春の扉→ここ、という感じ。その手前の季節の扉までの行き先を指定する)

 として、ある夏の扉を使っていく場合の数を考えたとき、春の扉たちの場合の数の和がその値になる。……ということは、春夏秋冬それぞれについて和を取って良い、ということになる。

 なお、扉の総数を求めるとき、modで割ってしまいWAを出した。ベキ乗する値にmodを取ってはダメ!

2023年6月14日水曜日

東京海上日動プログラミングコンテスト2023(AtCoder Beginner Contest 304)

  Fまで六完。


Ex - Constrained Topological Sort

 解説放送を見てAC。

 これは自然な条件を積み重ねていけば解法へたどりつける問題だった。粘れば自力でも解けたかなぁ……。

Educational Codeforces Round 150 (Rated for Div. 2)

 Dまで四完。

コンテスト後のツイート

E. Fill the Matrix

 横に何マス繋がっているか? が何個ずつあるかを分かれば良い。
 それは最大長方形のアルゴリズムを使えば解ける……という情報を得てAC。

 スタックを利用して最大長方形の面積を求めるアルゴリズムが頭に入っていなかったのが一番の問題だった。実際、「最大長方形」という文字を見てもピンと来ず、検索してどういうアルゴリズムだったかを思い出したら解法が分かった。

 典型アルゴリズムを頭に入れておくのが大事。

2023年6月12日月曜日

ALGO ARTIS プログラミングコンテスト2023(AtCoder Heuristic Contest 020)

 途中までは結構良かったものの、後半伸ばせず188位でした。

コンテスト後のツイート


2023年6月11日日曜日

yukicoder contest 392

 全く提出していないけど、一応コンテスト中に問題は読んだので参加(?)


No.2343 (l+r)/2

 解説AC。
 "010101……"に帰着されることはまあ確かに、という感じだが、その後がびっくり。

No.2344 (l+r)^2

 解説AC。

 ある操作回数後のmod 2^xが分かれば、もう一回操作した後のmod 2^(x+1)が分かるというのが凄い。
 M=1ならパスカルの三角形を使えそうなのは分かるので、「mod 2^xについて良い性質が成り立ちそう」と考えたくなるのは分かる。とはいえ、そこから思い付くのは難しいが……。

2023年6月8日木曜日

日鉄ソリューションズプログラミングコンテスト2023(AtCoder Beginner Contest 303)

 Eまで五完。

コンテストへのリンク
コンテスト後のツイート


F - Damage over Time

 自力AC。

 答え二分探索。どの呪文を優先して使うかは、$t_i*d_i$が大きい順にソートしておく。さらに、同じ$d$なら長い$t$のものだけを使うといった枝狩りもする。

 あとは、時間Dの間に最大何ダメージ与えられるか? を計算できれば良い。

 次の呪文に移るべきタイミングは計算できるので、x日~y日までで何ダメージ与えられるか? が求まればよく、これは、全体($t_i$日全てダメージを与えたとき)から、実際はダメージを与えられない日が最大何日・最小何日かを計算し、その平均を引けば良い。

 コンテスト中もこの方針で考えていたが、最後の立式で混乱し、一時間考えてもサンプルが合わなかった。が、今やったらあっさりACすることができて不思議な気持ちになった。
 時間が経って頭が整理されたのかなぁ。


 G - Bags Game

 解説AC。

 区間DPを高速化すれば良いという方針自体は(自分は解説を見てしまったが)分かりやすいが、実装がとにかく大変だった。

 添え字を合わせるのがしんどいだけでなく、自分のセグ木による実装だとPyPyでは通らず、RUSTに直してなんとかACした。

 方針は簡単だがACするのは非常に厳しい問題なので、AC人数が伸びなかったのもよく分かる。