第二回日本最強プログラマー学生選手権

ABCDFの5完。内容はともかく久しぶりの黄パフォ相当でよかったね。このヤバげなセット(8問でそのうち3問が600らしいことは「あーだこーだー」で聞いていた)をratedでやりたくないなあと先週から思っていた。

A - Competition

消費時間において問題文の読解が支配的になる。考察もかなりしんどい。グラム当たりの価格が等しくなるような価格を求めればいいと気づくのにかなり時間がかかった。そしたら、それよりも小さい最大の整数を求めればよい。等しくてはいけない。掛けてから1を引けばいいという実装方法も難しいし、それで正しいという証明もわからない(結局場合分け)。

B - Xor of Sequences

概要を把握してこれは難しいやつだと思いcpprefjpへ行きset_symmetric_differenceを持ってくる。内容的に10^5と思っていたら10^3だったが、今さら方針を変えるのはかえってタイムロスになる。A, Bがソート済みなのは今気づいた。

C - Max GCD 2

難しそうではあるけど、愚直でも2乗にlogが付く程度なので何か高速化するだけでいいから気楽なところはある。gcdは高々2*10^5なので公約数になるか1から全部試せばいい。以前作った、整数を渡して指定方向で最も近いmの倍数を返す関数の出番が来た!b以下の最大のiの倍数とa以上の最小のiの倍数の差がi以上ならiが公約数になる。

探索範囲をa以下にしてWA。なぜこんな間違いをしたのか、次のDを考えているときも尾を引いた。最大公約数はb以上にならないからaみたいな感じかなあ。テキトーすぎる。たまに自分の中身が見えると醜くて目を背けたくなる。答えのわかりやすい上限が見えなかったというのが原因として大きそうではある。整数x, y(0 < x < y)の公約数はy未満であり、y未満のyの約数のうち最大のものはyが偶数ならy/2、奇数ならそれより小さい。というわけでB/2以下を調べればよさそうだけど、あまりすっきりしない。現実的にはB以下だったかなあ。

D - Nowhere P

なぜ「とても」が付いているのかわからない。列の要素が0であってはいけない。なんか制約を見るのが遅れる。DPっぽいと思ったところでどっちも10^9だと気づく。列の長さがP未満と思ってその性質を探ろうとしていたこともあったな。

まあ順番に作っていくだけ。最初の要素はP-1通りのどれでもいい。次からはそこから0に行くルートが必ずあるのでそれを除いたP-2通り。簡単すぎる。俺は何の幻影を見ていたんだ。

E - Level K Palindrome

空文字列の扱いがなんかおかしい。文字数は変えられないが中身は自由に書き換えられるので、判定だけなら簡単そう(レベルKの回文になれない文字数の範囲は2倍ずつ増えていきそう)。そこをクリアしたらレベル0回文となる長さ1以外の文字列をどう設定するかが本質っぽい(最小の書き換え回数で回文でなくするのが難しそうで諦めた)。あと挿入する1文字を揃えるのも大変そうではある。実装してないけど、実装でかなり実力が出そうだなと思った(自分は苦手そう)。

(追記)コンテスト後、実装した。かなり迷ってやっぱり再帰しかなかった。レベルが1小さいものに分解していくのは真ん中で切るだけなので簡単。奇数長の回文の真ん中の文字はレベル毎に全部一致させる必要がある。再帰しながらカウントしてレベル毎に文字数が一番多いものに合わせる。レベル0に到達したら、真ん中の文字の処理は同じようにしたうえで、stringのvectorにpush_back。その際、レベル1の後ろ側の文字列だったら反転させる。そうして集めた同じ長さの文字列たちについて同じようにカウントして(真ん中があればそこはやらない)、二番目に多い文字数と具体的に一番多い文字の一つを求める。その文字をつなげたものが回文なら二番目のうち最もダメージが小さいものに替える。再帰と決めてからは手が動いていたけど、時間はかかった。コンテスト中に通すという意味ではスピードが足りないが、普通に書き切ってACできたという意味では自分の実装力にわりと満足している。

F - Max Matrix

最初のうちは1列全部Yに書き換えるだけ。同じ列に書き込むときも一旦0に戻してから改めてYをセットすればよさそう。もう少し考えると、単にY以上は個数がわかればよくY未満は和がわかればいい。Yが小さければBITで行ける。何か手段がないかしばらく考えたが、結局座標圧縮。最近はlower_boundを使う構築も慣れてきた。Yを全部まとめて(a, bで分けず)vectorに突っ込みsort, unique、そこをlower_boundでクエリのYを番号に置き換える。unique後のサイズでBITを4個確保し、a, bそれぞれでの個数と和を持つ。あとはクエリを順番に処理していくだけ(ここで添字をどっちにするかけっこう混乱した)。終わってみれば普通の問題。「最初の6問は通常のABCと同じです」という今日のAとEはかなり難しく、その空気に圧されていた。

G - Spanning Tree

まずサンプル4の11^9がわからない。