ACPCVC20200615 復習メモ
https://kenkoooo.com/atcoder/#/contest/show/de1c2a21-407e-41a6-bc64-deb6570852f3
3問目のJOI感に少しの興奮を覚えた
A - パズル
パズルになっていて、ステップ数も ステップ以内とあまり大きくない。onlinejudge.u-aizu.ac.jp
この問題を解いていると、 これは IDA*で通るなという確信が付いているので数字が規定の位置から離れているマンハッタン距離をヒューリスティック値にしてやると、通る。
潜るにしろ、 的はずれなところに 回くらいいく事とかなさそうなので (ヒューリスティック値が増える方向に進むとステップと合わせて とか上がったりする)、かなり小さくなるんじゃないかなっていう感じにはなっている。 ちゃんと計算量解析したいけど難しそう…
B - 擬二等辺三角形
細かい計算が必要でかなり精神を使う辺を みたいに書くとすると、 もう 辺を使って三角形になるのは、 である。あと、途中で の長さまでしか使えなくなってくる。
しかも、 みたいになっていると、重複して計算してしまうところが出てきたり、 そもそも、 最後の辺の長さについては は使えないとか色々とめんどくさい制約がある。
とりあえず、 の中に がある場合を考えると、 みたいな制約が出てくるので、解くと、 まではそうらしいことがわかる。
そこで分けて、あとは数列が定められるのでこれらを で求めて終わり
数列を頑張る処理は場合分けとか重複部分の排除とか嫌な気持ちになることが多々あるので精神力を使って頑張って殴って解く。
一般化の式とか書くと多分頭がイカれてきそう()
C - 映画の連続視聴
次元のDPとかがかなり浮かびやすい。 の累積和を取っておいて、連続した試聴に対して直接エッジを張ることを考えると、 状態 , 遷移 の のDPが出来そうで、 よりかなり現実的これはもちろん主要な時間だけ取り出す事で実現できているので座標圧縮が必要になる。
ところで、エッジの貼り方はどうすればいいだろうかということになる。
ある特定の時間からある特定の時間まででできるだけ同じ種類の多くの映画を見れば、できるだけ大きい得点になるので、そのような最適なスケジューリングをしてエッジを張って行くことが必要になる。
そこで、まず種類別にする。そして区間の終点でソートする。ソートした後、貪欲に映画を見ていくのが最適になる(これは蟻本とかに書いてある)。 このような見方をするたびに、所定の位置にエッジを張っていくと、グラフが完成するので、それをDPで最大化すると、この問題は解ける。
こういうたくさん組み合わさっている系の問題ってJOIみがないかな(わからない)
感想
何回も思っているが、考察はできるだけ詰めておこう 出来そうになかったらサンプルをたくさんためそうABC170 参加メモ
温まってる時に限って精神が安定してるな
243th Perf=2069 1846->1870(+24)
Highestあたりにまた戻して行かないといけないので頑張ります
A - Five Variables
一つづつ判断してもいいがforで回して か判断するのが早そうB - Crane and Turtle
最小が でそこから二本ずつ増やして に出来るので、 は偶数で になっていれば "Yes" と出力できる。C - Forbidden List
値を全探索する。flagとかで使ったやつを管理すればいい と が答えになることがあるということに注意D - Not Divisible
みたいな条件で が で割れることはないので小さい順にソートしておくがそれぞれ の倍数を全て埋めていくと(エラトステネスみたいに)、 が呼び出された時に割り切れるかどうかがわかるので、やっていく。
計算量は調和級数になるので
E - Smart Infants
現在の幼児の位置を管理して、それぞれ一番大きい値を出せるようにすればいいので、 個 multiset を用意してやるとそれぞれの幼稚園で一番大きい値を取り出せる 移動とかも出来るその一番大きい値たちを multiset に入れておくと、小さい値がいつでも取り出せるので この問題を解ける。
F - Pond Skater
普通にエッジ張って幅でやると言っても、使ったマス以降はだいたい使わなくていいので、そこで くらいで行けそうだなってなる。気をつけるべきなのは、異なる方向で進んでいて、同コストになっている者同士は同じように見てはいけない。そのため、方向を持ちながら条件に気をつけてやると、ACする。
なんか見落としがありそうなので、嘘解法なんですかね(知見のある人教えていただけるとありがたいです)
感想
Eまでは順調だったが、Fでかなり時間をかけてしまった。やっぱり実装力が落ちている気がするな。
とはいえ今はAtCoderだなという感じがある(同じこと毎回言ってる気がするが)
引き続き精進したい。
東京海上日動 プログラミングコンテスト2020 参加メモ
レートがどんどん下がる みんなに抜かされていく 824th Perf=1672 1864->1846(-18)
そんなことも言ってられないのでちゃんと参加メモを書きます
A - Nickname
これはひねりがなかったのですぐ解けた S.substr(0, 3) をして終わりB - Tag
逃げる方向とかを固定したかったので になるように矯正すると、相対速度 と の積が 以上になっていれば捕まえられる。
これを適切に描いたらAC long long とかにしておかないと掛け算でオーバーフローするんじゃないかな
C - Lamps
思いつくまでに時間がかかってしまった操作は 回くらいすると、全ての数列が になってしまう。
これだけ気づければもう終わりなんだよね…
こんな感じで理由を説明すればいいかな。
まず、とりあえず 回操作すると、全ての数列は 以上になっている。
その状態から、ほとんどの数の寄与が操作毎に になっていくので、
回くらいで全部 になるという見通しがつく。
端を考慮した証明してくれている人とかいるのかな
操作自体は imos法を使えばいいので でいける。
よって である。
回やると制約上で全部行けるらしい。
D - Knapsack Queries on a tree
これ通したかったな…
先祖だけしか見ないので、各クエリ毎に要素は 最大 個くらいしか呼ばれない。
ただナップザックは制限がない状態だと になっているので、まあここでやるとしたら半分全列挙くらいしか無いだろうって思う。実際に計算量を考えてもぎりぎり通りそうっていう感じ。これだけだと通らないんだけれども。 9 9 で分けても通らない。
ここで、もうひとつ事実に気づくべきなのは、 根の方の要素の組み合わせは少ないので、こっちを前計算で求められるということである。
例えば深さ のノードそれぞれに対して全列挙を求めてあげても、 くらいの計算量にしかならないので、こっちに半分全列挙の比重をかけてあげる。
そうしたら、残り 個に対しての列挙をしてそれで、 個の方の列挙した奴に対してupper_boundとかかけて計算すればいいので、 結構計算量が厳し目だが通る。
感想
Dみたいな問題は計算量が通りそうだから祈りながらコードを書いていると死んでしまう。祈るくらいなら、もうちょっと考えたほうが良い。
ACPCVC20200518 復習メモ
かなり遅れました。全部書きたいです。
A - ConvexScore
ある のスコアは であるが、 これは内包されている点たちの集合を と置いた時にその部分集合の個数と一致する。ここで、ある凸多角形を決めたときに、その内部のパターン数を求めて、全ての凸多角形に対して数え上げれば良いという問題①に落ちる。
ここで、 点以上からなる凸包の面積が正になっているような点の集合の個数を全て数え上げるとする。
すると、それぞれの集合に対して凸包が一意に定まっているし、全ての凸包を網羅するので、①の答えになっている。
そのため、 すべての点集合の個数 から、 空集合、 点しか無い集合、 点以上の直線になっているものの集合の個数を引いてあげれば答えが出るということになる。
空集合の個数は , 点しか無い集合の個数は である。
点以上の直線になっているものの集合の個数は、 それぞれの直線で考えていくが、ある直線上に 点乗っている場合、 それらの 点以上の集合の個数は となっているので、 それぞれの直線に対して で計算してあげると、 最終的な答えが求まる。
スコアの性質をうまく使わないと解けない問題だった。
B - Bichrome Tree
ある部分木 があって、その根を としたときに、その の持つ重みの和がどちらかが , もうひとつが何らかの値 みたいになる(白黒は関係なくて、どっちの色でも のペアは達成できる)。 この を最小化しておけば、 より大きい部分木に対して一番有利に働くだろう。そこで、
… 根 の部分木について、自分の色じゃない方の重み の最小値
と置く。これに対する漸化式が求まれば、 の値が存在するか否かで作成可能かそうでないかが分かるはずである。
ここで、ある部分木の根を , の子を とする。
たちは それぞれ、 , の値を持っているが、どちらかを を構成する重みに割り振るか、そうでない方に割り振るかという選択を行うことが出来る。
すべて選択した後、重みの和が 以下(頂点 自体も重みを割り振れるので になるように帳尻合わせが出来る) になっているものに対して、 もうひとつの値 が一番小さいものを選べばいいということになる。
とすると、これも DP を用いて解くことが出来る。
... 現在頂点 まで見た時に を構成する重みが現在 になっているときの、もうひとつの値の最小値
これを使うと、 とすることができるので の漸化式が求まった。
は 頂点 の子の数とする。
3重ループになるから一見間に合わなそうだが、辺の数は しか無いので になっている。
C - Four Coloring
これはグリッドを 度回転すると、ある点 から距離が であるような点は を中心とした正方形を描くことになる。この条件でやると、どうやら、 辺 の正方形を敷き詰めてもその正方形の点同士は条件を壊さない。
周辺が危険になっているので、他の色の正方形を敷き詰めることを考えていくと、
赤青赤青
黄緑黄緑
赤青赤青
黄緑黄緑
みたいにすると、何一つ条件を壊さないようなので、このまま 度回転して元の座標に戻すとOK
感想
直感的にCのほうがBよりdiff高いのなんか違和感があるAみたいな問題は考察を間違えると、かなりドツボにはまりそう。 全然わからなかったら一回リセットして考え直してみるといいかも知れない。
反省
面白くない駄文ですが書きます。競プロの時間を減らして色々なことに手を付けているつもりだったんですが、やっぱりつもりだったようです。考えてみれば何も達成してないのに他のことをやる意味がなかったです。今の所、学業と競プロをやり続けなければ、自分に何の価値も無いようなので頑張ります。
このまま、社会性も実力もないのでは、将来大したこと無い事をしているヤバイおっさんに成り果てそう
ABC165 参加メモ
発想自体は思いつきやすいが、そこからちゃんと詰めて書けるのかというところを頑張るべきだった。躓きすぎて5ペナABCDE5完(91:40+25:00)
1974->1945(-29, Perf = 1642, 859th) 調子悪いにしたら激冷えにはならなかったなと思っている
A
そうだよなあ…b/k*bで位置が出てくるわけだからそれがA以上なら包含してるんだよなあ条件ミスって1WA
B
val += val / 100ですねなんか思いつけなかった
C
こういう組み合わせは仕切ると出てくる。すると最大でも くらいになるみたい
つまり全列挙してそれぞれポイントを計算すると くらい出てくる
D
とりあえず のときだけ考える見た感じ、 は とかにしておくと良さそう(それ以外は まで数を上げると だけ無条件に値が上昇するので最適解は の中にあることが分かる)
もう実は の上限は小さいので十分間に合うけど、実は答えは のときになっている。
理由は の解が のときと一致するからである。
あと言ってなかった のときは、 のときが一番大きいので、まとめると、
のときが答えである。
E
ダメな条件を列挙してみる とするともし だったら、 になっているので、 みたいになるようにやっていけばかぶらないで済みそう
実際、 という制約があるので頑張れば見つかりそう
差が奇数同士のものを集めると、例えば
1 6みたいに入れ子にする発想が出る。
2 5
3 4
同じように偶数もこの入れ子の隣とかに
7 11みたいにおいておくと、今の問題なら について解くことができた。
8 10
これをちゃんと一般化して解けば終わり
F
LISを1段階戻す操作が適切にできれば解ける。
木が分岐しているときはある一方を深さで進めて処理したときにもう一方をやるにはLISの状態をもとに戻してからやらなきゃいけない。
もとに戻すにはLISの挿入操作をする前に 挿入するところのもとのデータと位置さえ持っておいて、戻すときにそのデータに戻せば でできる。
適切に潜ったり戻ったりして、その際に操作を行えば、すべての についてサイズは求まるので で解けました。
感想
スムーズに行かなかったなあ、Fにたどり着く前に時間をかけすぎてしまったタイムスケジュールをきちんと組んで競プロに望んでいくのが好ましい。
ABC164 参加メモ
1ヶ月位競プロをしていなかった(生活も難しい)
ただ、Ratedのコンテストには出続けていた(そうでなければ自分の実力を確かめられないため)
今回は問題(特にD, E)が自分にとって解きやすかったのでそこで速解きしてパフォは良かった
1929->1974(+45, Highest) Perf = 2311
A, B, C
Aは数の比較して終わりBは で倒すターン数が分かるので比較して終わり
Cはsetに入れるとできる
D
この問題はABC158-Eを少し特殊にした版 だけどABC158-Eの解で十分間に合うのでそれでやるtinumukiti631.hatenablog.com
要点はSuffixに関する答え は で求められるのと、 と は互いに素になっているので、 になっていれば部分文字列は で割り切れることになる。つまり、 であるような を求めればいいので、これはmapとかで左から数を記憶しながらやっていくと、求めることができる。
E
高校の頃に最短路系の問題はかなり解いた気がする。ヘビのJOI君(JOI2016-2017-yo6)とか解くとこういうのは思いつくと思う
まず、最短時間を求めたいけど、銀貨が減るので補填しながら行かなければいけない。
ただ、[現在の駅][銀貨の数] の条件があれば、答えを最小のものにまとめても大丈夫
ところで、消費する銀貨は エッジで までになっているので、 回移動することを仮定しても くらいにしかならない。 よって、大体配列のサイズは 程度になる。
の重みで銀貨を だけ増やすエッジと、銀貨を消費しながら だけ重みをつけて駅を移動するエッジの2つを適切に貼れば、あとは Dijkstra することでこの問題は解ける。
F
発想自体はそんなに難しくないと思う、実装がきつすぎるんだよな。実装の方針をちゃんと立てるのは大事。というか、実装方針に関する考察という概念が競プロにはあるんじゃないかと思う(これは言わずもがなかもしれないが)。
まず、bitごとに操作が独立なので、bitごとに考えるという方針ができる。(ここで、 は に対して着目しているbitの値ということにしておく。)
の値はとりあえずすべて にしておく。どんどん を増やしていくというやり方だ。
次に、 について でなければならないところと にしても解に影響を与えないところを考える。
でなければならないところは 列か行に対して「論理積が 」である。これを探して、適切に にする。
にしても解に影響を与えないところは、論理和論理積にかかわらず、 であるようなところである。このようなところは、 になっている利点がないので にしてしまおう。
このようにしておくと、条件を満たさないところというのが、 「論理和が になる必要があるような行または列でまだ になっていないところ」に限定される。
まず条件を満たさない行について考えると、行の中の要素のうちどこかを にできればいいわけである。
にするのが許される列は、「論理積が 」の列に限る。このとき、その列にある の数が 以上あれば列の値を に保ったままにしながら 要素を に変換することができる。
このような列を見つけながら各行やっていくと、行に対する条件を満たせる。
列の条件も上記のことを同じようにやっていけば満たすことができる。しかも独立なので行の操作に依存していない。
これで は完成する。これは の解を持つものに関しては必ず正しいものを構築できる。ということは、正しいものを構築できていないものは の解を持たないということになるので、 が条件を満たしているのか判定して満たしていないものを を出力すれば良い。
その他は、 として出力する。
こういうのを解くときは、データに関する統計みたいなものを出しておいて、いつでも使えるようにしたほうが嬉しい。今回なら「ある行(列)の 0 の数, 1の数」とか。大体、統計を出しておいたほうが実装が簡単になることが多いし、シミュレーションできるので頭が壊れることがないんじゃないかな。
感想
今回は山を当てたけど、苦手な問題を苦手のままにしておくと、よくない。ABC128, 129 DEF バチャ
not-522.appspot.com
toyamaくんが参加してくれました ありがとう ありがとう
AB, DE解いて4完でした(400, 500に結構つまずいたというのもあったので反省)
Cが惜しかったです
今回はABCDEの解説をしてFは次のバチャで解きたいと思います
A: ABC128-D - equeue
操作Cや操作Dを先にやるのは明らかに無駄なので操作A, Bが終わったあとにやる。すると、操作C, 操作Dはただ宝石を捨てるだけの操作になる。
こうすると、操作Aを何回やるか, 操作Bを何回やるかを決めると、何回宝石を捨てられるかがわかる。
操作Aを何回やるかと、操作Bを何回やるかを決めて取り出す->負の価値を持った鉱石を出来る限り捨てる
で決め打ちした時の最大値が出るので、後は全通り試して終わり
B: ABC128-E - Roadwork
座標 が 時刻 のときに通行止めになっていると、 時刻 に出発した人が止まらずに座標 に来た場合に通行止めを食らうという考察が出来る。番目の人は通行止めを食らう可能性のある座標のなかで一番座標が小さいものに対して実際に通行止めを食らうことになる。
そのため、 番目の人を見ている時に、通行止めを食らう可能性のあるものが列挙できていて、かつ一番小さい座標を持てれば良い。
それをするには、 始点と終点である を の座標に対応させて(座標圧縮?)、 それぞれ、 を insert, erase するようなマークをつけておく。
そして、setやmultisetを使い、左から、命令に従って insert, erase をするようにする。
setの中のそのときの一番小さい座標を取り出して、おわり
C: ABC128-F - Frog Jump
動きを確かめてみると、図のようになっていれば問題文を満たす動きが出来ることが分かる。動いていくと、偶数回動いた先である赤丸と、奇数回動いた先である青丸に分かれる。
赤丸は座標 から伸びており、 青丸は 座標 から伸びている。
そして、図で書いたような条件があれば、手順2 と手順3のような動きを実現できる(矢印で実際に構成できているように)。
このような と赤丸, 青丸の数の決め方は、 程度しか無い(調和級数)ので、 に対して簡単な累積和を行って求めることで、 で求められる。
境界条件があって、気をつけないといけないのは、赤丸と青丸が被らないかどうかと, になるように動けるかである。
D: ABC129-D - Lamp
上下左右どのくらい'.'が連続しているかを4方向累積和を取って全部足して-3すると求まる。1-indexed で解けば良かったな てこずってしまった
E: ABC129-E - Sum Equals Xor
典型的な桁DPを満たすには、 のある桁が 同士になっていないことが条件である。
あとは が より大きくならないように調整してDPする。
… から 桁まで同じ値を選んできたために、 以下になるかどうかが保証されていないようなものの個数
… から 桁のどこかの桁について小さい値を選んでいるので、答えが 未満になることが確定しているようなものの個数
この遷移をちゃんと考えて桁DPすればオーケー。