AtCoder Beginner Contest #121
A. Cells
残った白い部分を左上に詰めると考えやすい気がする(ABC106Aの解説のように). 解答例
B. Can you solve this?
Yes. 数式をそのまま実装すればよい. 解答例
C. Energy Drink Collector
安いものから買っていくのがよいから,(値段,個数)のペアを値段で昇順ソートし,この順番に残り購入数がになるまで買う.C++だと結構大変そうだがOCamlだと楽できる. 解答例
D. XOR World
bitごとに決めていく解法はすぐに浮かんだものの実装が複雑になってしまったため考察をした.この種の問題に適用できる定石をすっかり忘れていたので反省. 解答例
偶数とその次の数とのxorは必ずである.これは最下位ビットがからになるだけの違いであるため.この性質を利用するために偶数と奇数のペアを基調に考えていく.
これによってに最も近い偶数からに最も近い奇数までのxor結果はで求まる:の偶奇で場合分けすると,左端はが偶数のときはを選べばよく,奇数のときは.右端はが奇数のとき,でなければ(となるような場合,すなわちの場合は個別に処理しておく).この中のxor結果は,偶数と隣り合う奇数のペアが個存在することから,これが奇数であれば,偶数であれば.
あとは余りを処理すればよい.まずのときはと先の結果とのxorが必要.右側についても同様に,とを比較してであればとのxorも計算する.これにより所望の値が求まる.
別解1(editorial)
区間に関する問題はの解が求まればとの結果から求められる場合がある,という定石を用いるのが簡単だった.いまそれぞれの範囲のxorは先の方針の一部であるから簡単に求まる.ここでxorの逆演算がxorであったことを思い出すと,を計算すればよい(記号は適当). 解答例
別解2(editorial)
先に述べたビットごとに決めていく解法のリベンジ.やはりとを同時に考えるのは厳しそう.そこでこの解法でもを求める方法から考えることとする.
まずxorは桁ごとに考えることができるため,そのようにする.いまからまでの整数を2進数表記で並べると,各ビット(下から順にとする)では,のそれぞれ個の並びが交互に現れる.いま一つのを1単位と考えると,1単位分のxorの値はの個数からのとき,それ以外のときである.において,ビット目までにある単位数は切り捨てで個であるから,繰り返し部のxor和はのとき,それ以外のときである.
加えてループの余り部分も考える必要がある.この長さはとなる.これがを超えている場合はその数だけが含まれるため,を計算すればよい.これと先のxorの値とのxorをとれば,それがその桁の値となる. 解答例