AtCoder Regular Contest 114参加記(~B問題)
早解きの巻
A - Not coprime
互いに素でないということは、とに共通の素因数が存在するということと同値である。制約より、は最大でも以下の素数の積(およそ)にしかならない。さらに、以下の素数それぞれに対して「に含めるか」「含めないか」の2択を選ぶbit全探索をして全通り試してもも実行時間制限にも十分間に合う。
ちなみに以下の素数は個。素数リストを実行時に生成してもよかったが、ライブラリを引っ張り出してくるより暗記しているものを書き出したほうが早かった。
計算量は、。
B - Special Subsets
全射の整数集合が与えられていて、その部分集合のうち全単射であるものはいくつあるか?という問題。(たぶん)
この集合と関数の関係は、へと有向辺を生やしたグラフと等価である。このグラフは、頂点数と辺数がそれぞれで等しい。
また、関数が全単射であるとき、有向グラフはいくつかの重複しない閉路のみからなるグラフとなる(必ずしも連結とは限らない)。
つまり元のグラフのなかに閉路がいくつ存在するかがわかればよい。これは単純にDFSで閉路判定をすればよいし、「頂点数と辺数が等しいグラフの閉路の数は、連結成分の数に等しい」という定理をもちいてUnionFindなどを用いて連結成分の数を持つだけでも良い。
閉路の数をとすれば、答えはである。
計算量は、。
感想
Cは解けなかった。サンプルが合わなかった。
D問題をみて「貪欲かな~」と思ったけど、順位表を見るとD-EのAC数が逆転していたのでC問題をずっとにらんでいた。貪欲は嘘解法らしく一安心。
個人的に早解きで暖まるのは申し訳ない気持ちになる。
AtCoder Beginner Contest 194参加記(~F問題)
Fがむずすぎる
青パフォ
B - Job Assignment
問題文を読んだ時点で、計算量がでも解けることを確信したので制約を見ていなかった。実はでも通るらしい。こういうところで実装をサボらないとなんだか損した気分になる。
コンテスト中は場合分けしてで解いた。
1. 仕事 A と仕事 B をそれぞれ別の従業員に割り当てる場合
の最小値を、の最小値をとする。
分で仕事ができる従業員と、分で仕事ができる従業員がそれぞれ別になるように割り当てられるか調べる。具体的には、
・となるようなが2個以上ある場合
・となるようなが2個以上ある場合
・となるようなが1個のみ かつ となるようなが1個のみ かつ
のどれかの場合、答えはとなる。上記に当てはまらない場合、を満たす従業員が仕事Aか仕事Bを行うのは確定しているので、従業員を除いた人の中で一番早く仕事Aもしくは仕事Bをこなすことができる従業員をkを探す。よって答えはとなる。
2. 仕事 A と仕事 B をどちらも同じ従業員に割り当てる場合
答えはの最小値である。
これらの答えの最小値が最終的な答えである。
計算量で解くなら、従業員のペアを全探索してシミュレーションし、その最小値を求めればよい。
C - Squared Error
式が正しいかどうか自信が無いがとりあえず書いておく(間違ってたらごめんなさい)。
式変形すると、
となる。
ここで、
であり、
である。これは累積和を用いることでで求められる。(参考:過去問に下位互換となる問題が出題済み。C - Sum of product of pairs)
よって全体でも計算量で答えを求めることができる。
D - Journey
わかってないけどAC。
まだ選ばれていない頂点が選ばれると、「すでに選ばれた頂点の集合(連結)」と連結になる。つまり、最初に高橋君がいる頂点1以外の頂点をすべて選ぶまでの回数の期待値は?という問題になる。これはたしかガチャコンプ問題とかいう名前(俗称)がついていて、結構頻繁に出題されている(のに、未だに理解できていない)。
期待値の求め方がわからないので「期待値 回数 計算」でググると高校数学の美しい物語さんがヒットする。
mathtrain.jp
ここにそのまま答えが書いてある。どうやら期待値は漸化式を使って表現できるらしい。種類すでに引いている場合の期待値を考えると上手くいく?
とりあえず漸化式が立てばそれを更新していくだけなので、計算量はである。
期待値の問題が苦手ということがわかったのでどこかで特訓したい(しない)
E - Mex Min
数列のなかで、連続する個のの最小値は?という問題。
関数の定義より、個ある整数の中に、とある整数が含まれていなければ、関数の返す値は少なくとも以下となることがわかる。なので、からまでの整数それぞれに対して、が含まれない区間の長さの最大値が求められれば良い。これは、数列を前から舐めていって、各整数の直前の出現位置をメモしておけば解くことができる。
あとはから小さい順に、整数が含まれない区間の長さの最大値は以上かを判定してやればよい。
計算量は、。
F - Digits Paradise in Hexadecimal
桁DPっぽさがある。
dp[i桁目まで確定][N未満フラグ][Leading Zeroを抜けたかフラグ][iビット目:iをすでに含んでいるか?を保持するフラグ(16bit)] := 総数
とすると解けそうだが、計算量が(dはd進数であることを示す、本門ではd=16)程度になり、これは回程度の計算が必要になるので間に合わない。
どうやら桁DPをしなくても解けるらしい。わかりません。
感想
Bがむずすぎる
SOMPO HD プログラミングコンテスト2021(AtCoder Beginner Contest 192)参加記(~E問題)
A - Star
高橋君が最後に 1UPキノコ ご褒美をもらったあと何枚コインを集めているかわかるなら、からその枚数を引けば必要な枚数がわかる。これは剰余算を用いて計算することができる。答えはとなる。
計算量は、。
B - uNrEaDaBlE sTrInG
まず前提として、「ある文字が英大文字か?」を判定する関数と、「ある文字が英小文字か?」を判定する関数を書いてしまう(標準で用意されているなら使い方を調べる)。こうすることで考えることを減らせるし、デバッグの速度も上がる。
文字列を先頭から一文字ずつ見ていき、奇数番目の文字なら英小文字か判定して、偶数番目の文字なら英大文字か判定すると解ける。一文字でも条件を満たしていないのなら答えはNo
である。
主要な言語だと配列や文字列の添え字番号は0から始まるので、奇数・偶数が入れ替わるのがややこしいところ。
計算量は、。
C - Kaprekar Number
とりあえず、とを実装する。これは、整数を文字列に変換してからソートしてまた整数に戻す、という処理で実現可能である。これらの関数があれば、定義通りも問題なく実装できる。の計算量はである。
この関数についての漸化式が与えられている。制約を見ると求める項は最大でも番目までなので、愚直に漸化式の定義通り計算しても間に合う。
計算量は、。
D - Base n
誤読した。1桁のとき、何進数でも以下になるじゃねえか!と思って15分経ったところでclarを投げたところ、10秒でテンプレ質問が返ってきたのでいったん別の問題に逃げた。
再び戻ってよく読むと、の種類数ではなく、計算して得られる値の種類数を求める問題だった。なにこれ?あほくさ
の長さが以上のとき、の値が大きくなると得られる値も大きくなる。つまり、について条件を満たす境界を二分探索で探すことができる。の長さが大きい時、が1増えるだけで指数的に増加する場合があるのでオーバーフローに注意しながら実装すること、解が種類になるパターンもあること、の長さがのときの場合分けなど、考えることが多い。しかも問題文がわかりづらくて誤読したせいで解いた時の達成感が無かった。クソ
計算量は、。
E - Train
都市を頂点、鉄道路を辺と見たグラフを考える。このグラフの頂点から各頂点までの最短コスト(問題文中では到着までにかかる時間)を求めたいので、ダイクストラ法が適用できないか考える。
辺のコストが固定ですべて正のコストならばダイクストラ法を適用できる。もし列車が発車するタイミングちょうどに出発都市に到着した場合、コストはである。もし発車までに時間があるなら、その時間をコストに追加してやればよい。頂点への到着時刻をとすると、がコストとなる。よって、最短コストで移動している場合の辺のコストは固定であるとみなすことができ、すべて正のコストであるので、ダイクストラ法を適用することができる。
計算量は、。
F - Potion
まだちゃんと読んでない。DPっぽい。
感想
誤読も競プロのうちだけど、運営陣の発言を見てるとなんかモヤモヤするんだよなあ。どうにかならないのかな。
AtCoder Regular Contest 113参加記(~D問題)
いろいろ悔しい
A - A*B*C
最初、と誤読していた。サンプルで気付くまで15分かかった。ダメ。
は定数なので、たとえばを固定すると条件式がとなる。この式を満たす正の整数の組の個数は、以下の整数それぞれの約数の個数の総和に等しい。
よって、からまでの整数それぞれの約数の個数が高速に求められれば良い。これは計算量で求められる。これらの結果に累積和を適用することで、答えが求まる。
計算量は、。
B - A^B^C
進法でのの位というのは、の値のことを指す。なので、はじめにの値はで持って良い。
ここからの議論があいまいだが、ある程度大きい定数に対して
である。よって、の値がいくつか分かれば答えが求まることになる。具体的には、
- ならば
- ならば
- かつ ならば
- かつ ならば
- かつ ならば
- かつ ならば
となる。あとは計算して、最後にで割った余りを出力すればよい。例外的に、かつの場合は場合分けを通さずに実際にを計算した。
計算量は、。
C - String Invasion
手元で実験してみると、ある場所でaab
のような並びがあった場合連鎖的に操作が行え、文字列の末尾まですべてa
で置き換えることができる。また、aab...ccd...
というように2か所以上操作が行える箇所が存在した場合、より後ろにあるものから操作しても解は悪化しない。よって、文字列を後ろから見ていくことにする。
ある文字が連続していた場合、基本的にはその箇所より後ろにある文字全てが操作によって置き換わることになる。1回の操作で1文字置き換わるので、文字目と文字目が連続していた時、回操作を行える。
ただし、連続している文字より後ろに、その文字と同じ種類の文字が存在していた場合は操作を行えない。ただしそこで操作の連鎖がストップするわけではなく、それより後ろにある違う種類の文字に対しては操作できる。つまり、「文字目より後ろにある文字のうち、文字と文字の種類が同じである文字の個数」回は操作を行えない。この文字の個数は、「文字の種類」から「個数」を引ける構造を用意しておくことで簡単に調べられる。
以上の操作を文字列の後ろから実行して答えをカウントしていく。計算量は、文字の種類数をとして。
D - Sky Reflector
列A、Bを決めたときに矛盾なく数を埋められるか?を考えるとわかりやすい(と個人的に感じた)。
問題文の条件を言い換えると、
- 行に書き込める整数は以上以下
- 列に書き込める整数は以上以下
となる。さらにまとめると、
- マスに書き込める整数の範囲は以上以下
であることがわかる。
つまり、列の最大値をと固定すれば、各に対してが成立する。個ある要素はそれぞれ独立である。よって、最大値がであるような列の個数をとすると、をすべてのに対して求め、その総和を取ったものが答えとなる。ここでの計算量は、。
を求める。の値は以上以下なら何でもよいが、どれか1個以上はでなければならない。よって、
を満たすに対して、が成り立つ。ここでの計算量は、。
まとめると、全体の計算量は、となる。
…ただし、(または)の場合は例外で、マスに書かれた整数はなので、がすべて決まればの値も決まる。よってこの場合の答えはとなる。この場合分けを忘れて、コンテスト時間内のACを逃した…。(コンテスト後に気付いて場合分けを追加して提出したところ、ACした)くやしい。くやしい!!!!
感想
マジで悔しい~~~~
AtCoder Regular Contest 112参加記(~B問題)
スーパー場合分けコンテスト(ABのみ)
A - B = C
に変形すると負の値が登場しないので考えやすい。
各整数の下限がだった場合、を固定するとは通りとなる。この組の中でが未満のものは組、が未満のものも組あるので正しい答えはとなる。
これをすべての以上以下の全てのに対して求めるとよい。
B - -- - B
公式解説ではの偶奇で場合分けして考察していたが、僕はの正負(とゼロ)で丁寧に場合分けしてそれぞれの答えを書いた。
その中でさらに、よりでかくなるパターン、以上以下になるパターン、より小さくなるパターンにわけるとそれぞれの答えが簡単に求められる。
以上以下になるパターンの考察をミスして1WA。しょうもない。
C - DFS Game
部分木ごとに考えてよい。というところまではよくて、ある頂点から見た子の結果のうち何がわかれば部分木の答えが求まるのかがわからなかった。説明がふんわりでごめんなさい。理解してないからね。
その部分木に突入して戻ってきたとき、「片方が獲得できるコインの数」「もう片方が獲得できるコインの数」「戻ってきたときに次に子を選ぶ権利があるのは自分かどうか」みたいな情報があれば求められそうだった。が、これらの情報が子から複数来るので、何かの基準に合わせてソートしたりして選ばなければならない。わからない。
AtCoder Beginner Contest 190参加記(~?問題)
萎えてるので手抜きです
B - Magic 3
ループ
C - Bowls and Dishes
bit全探索
D - Staircase Sequences
N=A*Bと表したとき長さBで要素の平均がAであるような数列を考える
E - Magical Ornament
魔法石を頂点、「隣り合わせにできる関係性」を辺とみたグラフを考える
頂点C_iとC_jの距離をBFSで求めておく
架空の頂点0を追加してすべてのC_iとの間に辺を張ると始点終点を0とした巡回セールスマン問題と見れる
F - Shift and Inversions
見てねえよ
感想
D→A→B→Cの順で解いたあと、1時間かけてEを通したが、順位表を見るとEのAC数が821に対してFのAC数は1510であり、難易度逆転が起こっていた
2ペナかつ解くのが遅かったのもあり、問題単体で見れば青パフォのところなのにD早解きとほぼ同じパフォしかつかなかった
Eを提出してACが表示されたときはマジで膝を叩いて喜んだが、問題の体感難易度とパフォの数値が割に合わず興ざめした
自分がする対策としては
- 順位表を見て逆転が起きていないか常に監視する(マジで無駄)
- とりあえずすべての問題を確認する
- 全完できる実力をつける
- 早解き力を付ける
あたりだと思いました
AtCoder Beginner Contest 189参加記(~E問題)
DP回
100-200-0-400-500-0で0ペナ4完1200点。
B - Alcoholic
番目のお酒を飲んだ時のアルコールの摂取量は、 ml で求められる。番目から番目までのお酒をすべて飲んだ時のアルコールの摂取量を計算していき、初めてを超えたときのが答えである。で割ると誤差が出て怖いので、をで割るかわりにを倍すると整数のまま計算できる。
計算量は、。
C - Mandarin Orange
解けなかった。いや、解けてたんだけど制約を見て解は通らないと判断して書かなかった(いいわけ)。
を決めたとき、区間の最小値をとすれば、各皿ごとに個のみかんを食べることができる。を固定して考えたとき、を増やしたときの最小値はで更新できる。すべてのについて全探索して最大値を求めると、計算量はとなる。
実はこの問題は「ヒストグラムの最大長方形」の面積を求める問題に帰着できて(というかそのまま)、DPを使うことでで解けるらしい。へ~
D - Logical Expression
DP。
という感じの式を考える(ただし前から順に評価していく)。回目の計算が終わった時点での答えはTrue
かFalse
のどちらかである。それぞれの答えとなるような変数の割り当て型の個数をそれぞれとすると、回目の計算が終わった時点での答えも計算できる。
計算量は、。は、答えがオーバーフローしないための制約らしい。
E - Rotate and Flip
とりあえず、点を回転させたり線対称な位置に移動させたりする更新を式で表す。
- 時計回りに度回す
- 反時計回りに度回す
- を軸に対称移動させる
- を軸に対称移動させる
これらの式を眺めてみると、点の位置の更新は
という式で表せることがわかる。さらに、これらの更新する式は重ねることができる。の更新をする式を関数と見ると、関数の合成は次のように表せる。
式を整理して
とすれば、関数の合成をと一つの関数と見ることができる!(なげえ)
つまり、回目の操作から回目の操作までの関数の合成を累積和的な感じで計算しておけば、複数回の点の操作をで求めることができる。よって、各クエリにで答えることができる。
計算量は、。入力を受け取るのがボトルネック。
F - Sugoroku2
期待値、わからない
感想
簡単な処理なら10^8回の計算は1秒以内にできます