ABC260

5完。めちゃくちゃしんどいセットだった。

A - A Unique Letter

沼ってしまった。ソートしてif文でと思ったけど、コード量が多くなりすぎて方針転換。なんか見返すとソートしたことを使ってないんだよな(だからコード量増える)。楽な方針は、文字をカウントして1文字のものがあったら出力して終了、そうでなければ-1を出力、というもの。楽ではあるけどコード量はやはり多いため少し時間がかかる。3分以上使ってしまった。

B - Better Students Are Needed!

シンプルに実装問。受験生の番号をソートする。番号小さいのを優先するのは、予め番号でソートしてからstable_sortを使う。Aで降順ソートして先頭のX個をvectorに突っ込んでからerase。同様のことをあと2回やって、最後に番号をソートする(これを忘れてサンプル通らなかった)。方針を決めるのも実装するのも時間かかる。

C - Changing Jewels

怖い見た目。ABで疲れているところへこれはつらい。ただ、シミュレーションするだけな気もするのでその方向で考える。(レベルが違うならレベルが低いほうが下で)レベルが同じなら青のほうが下と考えると、操作によってより下の宝石しか生成されない。なので(?)操作の順番は関係ない。上から順に変換していくだけ。もう疲れてたんで答えの最大値の見積もりとかしなかった(サンプルに最大ケースがあるのは気づいてた)。ところで、レベル1の赤があってもレベル1の青が得られないの違和感ある。

D - Draw Your Cards

シミュレーション。表向きのカードが増えるときその増えたカードは場の表向きのカードの中で最大と気づいて、mapではなくvectorで行けるかと期待したが、山は消滅することがあるので諦めてmapに。遡るのが難しそうなのでmapにvectorを入れる(キーは見えてるカードの整数)。答えのvectorを用意しておく。カードを重ねるときはmapから削除してvectorに追加して新しいキーで挿入し直す。vectorの長さがKになったら挿入せず、mapのvector(山のカードに書かれた整数たち)を使って答えのvectorに現在のターン数を書き込む。

提出してTLE。びっくりした。mapに入ってるvectorは、ローカル変数のvectorとswapして取り出してるからここはmoveされて大丈夫なはず。insertがなんかダメなのか?と思いemplaceに書き換えてもTLE。一旦飛ばしてEに行った。Eを考えているときふと気づいた。ローカル変数のvectorはループの1回が終わってデストラクタが呼ばれるとき、提出したどちらのコードでも実体が残っている(map内にもあるのでつまりコピーされている)。insertするときmove(v)と書くように変更してAC。いやこのミスは酷い。何もわからずに書いていた。

(解説を見て)あー単に下のカードが何か持つだけか。なんか逆方向の単方向リストしか考えてなかった気がする(なんで)。解説にあった何枚目かの情報がなぜ必要なのかわからなかったが、実装を始めたらすぐわかった(K枚になったら消すんだよ)。

E - At Least One

とっかかりがつかめない。しばらくして、組をAでソートして区間を開始地点毎に考えることを思いついた。一番短くて終了地点はどこになるかをしゃくとりで求める。開始地点より前のAはBを採用するしかないのでその最大値を更新していく。Aの最大値はソート済みなのでわかっている。が、これかなり実装がしんどい。まず開始地点はBの最小値以下でなければならない。(開始地点以後にある)Aの最大値も、開始地点がAの最大値より後のときは単位元(今回は0にした)にしないといけない(と思ってたけどそもそもBの最大値はそれ以上なので例外処理は必要なさそう)。AかBかは対象になるのでまあ単位元が来ることもない。あとは普通のしゃくとり。

いもす法パートもけっこう難しかった。区間ではなく長さについてやるというのがややこしい。良い数列になる最小の長さで+1して、最大の長さ(区間の終了地点がMのときの長さ)の次の位置で-1する。累積和をとればできあがり。良い数列が存在しない開始位置は選ばないようにしてある。

F - Find 4-cycle

なんで二部グラフって書かないんだ?3000というのが微妙なところ。2乗もできそうだし、bitsetも考えたくなる。長さ4なので、辺や頂点を固定してもけっこう大変。T側から2個選ぶのを全部試す?残り時間が短かったので狭い発想にならざるをえなかった。

コンテスト後、改めて考える。DFSとか。S側から見て辺で直接つながってるT側の頂点を2つ選ぶことを考える。辺が3*10^5本あるかもしれないと思っていたが、よく考えると相手が3000しかいないんだから多くても3000本しか出てない。これは全列挙できる。3000*3000の配列にメモしていくぼんやりしたイメージ。S側全てについてこれをやるとき、3000本の辺が出てるやつは高々100頂点しかない。これも計算量はきつそうだが、ギリギリ行けなくもない程度だ。そもそも3000本の辺が出てるやつが2個あった時点で4-cycleは自明に存在する。ということで計算量が削減できるのではないかと考えると、配列に書き込むのは各場所に高々1回(2回目なら答えを出力して終了)なのでめっちゃ高速だった。

G - Scalene Triangle Area

同じ形向き大きさの三角形みたいな領域をカバーしてる。クエリ形式だけど、いもす法みたいにして全体を求めることもできそうだよな。あるいは、クエリ毎に逆向きの三角形を展開してその中を数えるのか。

(追記)いもす法というのを見て考えてみたが、四角形はできてもだんだん短くなる三角形は無理。視点を変えて、横に累積和をとれば完成という状況を考えてみると、プラスとマイナスを別々に生成できそうだ。なんか雰囲気がめっちゃ嘘っぽいけど正しいものは正しい(というほどは考えてないけど)ので実装してAC。N*Nの中で完結させたので、右にはみ出たとき左下にずらして配置するのが大変だった(下にはみ出るのはそもそも置く必要がない)。いもす法のサイトに三角形バージョンがあるのは言われてみればというか当然見たことあるんだけど全く思い出さなかった。難しいことを考えるのはつらいから、一歩踏み込んだ場所を全部避けて生きてるよな。こまったこまった。こまりミカン。