CODE FESTIVAL 2016 Grand Final C - Cheating Nim
問題概要
2人でNimをする。
はじめに 個の山があり、 番目の山には石が 個ある。
ゲームが始まる前に、それぞれの山から石を0個または1個取り除く。
後手が必ず勝つために取り除く石の数の最小値を求めよ。
制約
解法
Nimで後手が勝つためには、 すべての山の石の個数のxorが0でなければならない。
よって、この問題は、「それぞれの山から石を0個または1個取り除いて全体のxorを0にするときの取り除く最小の個数を求める」問題に帰着する。
はじめ、すべての山の石の個数のxorが で、石が 個ある山から石を1個取り除いた時、全体のxorは xor xor になる。
ここで、 xor は と表せるので、全体のxorは xor となる。
つまり、この操作において、全体のxorは下位 ビットのみが変更されることがわかる。
よって、 の上位ビットから順番に見ていき、 の ビット目が1だったら、 xor が となる山から石を1個取り除けばよい。
最終的に が0になれば取り除いた個数を出力し、 が0にならなければ-1を出力する。
より は高々32ビット程度なので、各ビットについて石を取り除く山をで調べても十分間に合う。
Submission #3024566 - CODE FESTIVAL 2016 Grand Final(Parallel)
「みんなのプロコン 2018」決勝 A - Uncommon
問題概要
個の異なる整数 と整数 が与えられる。
以上 以下のそれぞれの整数 について、 のうち と互いに素であるものの個数を求めよ。
制約
解法
ある数 について、 のうち と互いに素であるものの個数を求めるとき、愚直に1つずつ試して でやると全体で となりTLEする。
よって、互いに素であるものをまとめて計算することを考える。
6と互いに素なものは2の倍数でも3の倍数でもないものであるということを考えると、 と互いに素であるものは、 の約数の倍数を全体から引いたものであると考えられる。
前計算として、
f[ ] := のうち の倍数であるものの個数
を求めてあげることで、包除原理を使って と互いに素であるものの個数は高速に求めることができる。
Codeforces Round 498(Div.3) E. Military Problem
問題概要
頂点の根付き木が与えられる。根は1である。
ある頂点が命令を与えられると、自分の子のうちまだ命令が与えられていない1つの頂点(複数あれば頂点番号が最も小さい頂点)に命令を与える。命令が葉まで伝搬すると、自分の子のうちまだ命令が与えられていない1つの頂点(複数あれば頂点番号が最も小さい頂点)に命令を与えることを繰り返す。
個のクエリが与えられる。 番目のクエリでは頂点 に命令を与えた時に 番目に命令が伝えられる頂点を答える。
制約
解法
事前に頂点0からDFSをして、命令が伝わる順番を計算しておく。このとき、ある頂点に命令が伝わる順番を記録しておくことによって、各クエリにで答えることができる。
全体の計算量は
Codeforces Round 498(Div.3) D. Two Strings Swaps
問題概要
長さ の2つの文字列a,bが与えられる。文字列はともに小文字のアルファベットから構成される。
はじめに、好きな回数だけ以下の置換操作を行うことができる。
- となる を一つ選び、 を任意のアルファベットに置換する
その後、以下の3つの操作を繰り返して文字列a,bを等しくしたい。
- となる を一つ選び、 と を入れ替える
- となる を一つ選び、 と を入れ替える
- となる を一つ選び、 と を入れ替える
最初の置換操作の回数の最小値を求めよ。
制約
解法
- となる を一つ選び、 と を入れ替える
- となる を一つ選び、 と を入れ替える
- となる を一つ選び、 と を入れ替える
の3つの操作をすることによって、{, , , }を自由に入れ替えることができる。
また、 のとき、{, , , }と{, , , }は独立している。
よって、について置換操作の回数を計算して足し合わせればよい。
{, , , }の4つの文字が全て等しければ置換操作はしなくてよい。
また、{, , , }に2つの等しい文字が含まれているときも置換操作はしなくてよい。
そうでないとき、との片方だけを置換すればいいか、両方とも置換する必要があるかを調べればよい。
[追記:解法が一部間違っていたので訂正しました]
Codeforces Round 498(Div.3) C. Three Parts of the Array
Codeforces Round 498(Div.3) A Adjacent Replacements
問題概要
長さ の数列Aが与えられる。
次の操作を順番に行う。
- 数列Aに出現するを全てに置き換える
- 数列Aに出現するを全てに置き換える
- 数列Aに出現するを全てに置き換える
- 数列Aに出現するを全てに置き換える
- 数列Aに出現するを全てに置き換える
- 数列Aに出現するを全てに置き換える
- …
- 数列Aに出現するを全てに置き換える
- 数列Aに出現するを全てに置き換える
すべての操作が終わった後の数列Aを答えよ。
解法
が奇数だった場合, になった直後の操作でに戻る。
が偶数の場合は になった後は何も変化しない。
よって, が偶数の場合のみ1を引く。