AtCoder Regular Contest++ 233 A問題メモ

A - Strange Subset Sum

問題文

  • この問題は インタラクティブ問題です。
  • 正整数 $N$ が与えられます。
  • 正整数からなる集合 $X$ に対し、$X$ の部分集合であって総和が $N$ であるようなものを $X$ の特別な部分集合と呼ぶことにします。
  • ジャッジシステムは、以下の条件をすべて満たす集合 $A$ を隠し持っていますが、あなたは集合 $A$ の各要素の値を直接知ることはできません。
    • $|A|=\left\lfloor\frac{N}{2}\right\rfloor$
    • $A$ に含まれる要素は $1$ 以上 $N-1$ 以下の整数
    • 多重集合ではない。つまり同じ値は含まれない
  • あなたはジャッジシステムに対して以下の質問を $\left\lfloor\frac{3N}{4}\right\rfloor$ 回まで行うことができます。
    • $1$ 以上 $N-1$ 以下の整数 $a$ を選び、$a$ が $A$ に含まれるかを聞く
  • ジャッジが隠し持っている $A$ に特別な部分集合が存在するかを判定し、存在するならば $A$ の特別な部分集合の要素数の最小値を求めてください。
  • $1$ つの入力につき、$T$ 個のテストケースを解いてください。

制約

  • $1 \leq T \leq 5 \times 10^4$
  • $4 \leq N \leq 2 \times 10^5$
  • すべてのテストケースにおける $N$ の総和は $2 \times 10^5$ 以下
  • 入力される値はすべて整数

疑問

A問題、問題文に書いてあることと、ジャッジの挙動、違ってない?

問題文では、 「答えを求められたら、以下の形式で標準出力に出力してください」 「その後、次のテストケースが存在する場合は引き続きそれを処理してください」とある。 誤った答えが出力された場合の明確な記述はない以上、素直に読むと「答えの正誤に関係なく次のケースが開始される」ものと読める。

だが実際は(いろいろ提出して確かめた結果、おそらく) 誤った答えが出力されると、次のケースが残っていてもジャッジはEOFを出力し、対話を打ち切っている。 その後の挙動は言語により異なるが、 Pythonの場合は次の $N$ を読もうとして EOFError(ジャッジはRE)となる。

なお「ジャッジが -1 を返した場合、プログラムはすでに不正解とみなされています。この場合、ただちにプログラムを終了してください。」との記述はあるが、 上記の場合 -1 を返すこともなく打ち切っている。

もしそうなら、少なくとも「誤った答えが出力された場合、対話を打ち切る」ことは問題文中に明記する必要があると思う。

(REの解釈に相当無駄な時間を使った。これが実質的なWAであることを明記していないのは、さすがにどうなの、と思う)

解法

$1~N-1$ の中に、$(i,N-i)$ ペアが $\left\lfloor \frac{N-1}{2} \right\rfloor$ 個ある。
このうち、1つでも「両方が $A$ に含まれる」ペアが存在することが分かれば、答えは $2$ となる。

N=12   11 10  9  8  7 (6)
        1  2  3  4  5

N=13   12 11 10  9  8  7
        1  2  3  4  5  6

特に $N$ が偶数の場合、$\frac{N}{2}$ が含まれていないなら、 鳩の巣原理で必ずどこかに両方含まれるペアが存在し、答えは $2$ に確定する。 まずこれを確かめ、確定する場合は答えを出力して終了する。

以下、$N$ が偶数の場合は $\frac{N}{2}$ が含まれているとする。

$\frac{N}{2}$ より大きい値の集合を $U$、小さい方を $L$ とする。
$N=12$ の場合、$U=(11,10,9,8,7),L=(1,2,3,4,5)$ となる。

$U$ の各値が $A$ にあるか質問していく。返答は ○(Yes)と ×(No)に分かれるが、

  • ○ の方が個数が少なかった場合、$U$ で ○ だった値とペアになる $L$ を質問していく。
    • 1つでも ○ があれば、答えは $2$
  • × の方が個数が少なかった場合、$U$ で × だった値とペアになる $L$ を質問していく。
    • 1つでも × があれば、鳩の巣原理でどれかのペアは両方 ○ になる。答えは $2$

$L$ では $U$ の○×の結果のうち個数の少ない方のペアを質問することで、質問回数が $\left\lfloor\frac{3N}{4}\right\rfloor$ に抑えられる。

ここまでで確定しない場合、$A$ は一意に決まる。

N=13  →  |A|=6

  U  12 11 10  9  8  7      ○付き: Aに存在が確定
  L   1  2  3  4  5  6      ×:     Aに存在しないことが確定
  
・Uを全て質問
  U  ⑫ ⑪ × ⑨ ⑧ ×      12~7 を聞いた結果、左のようになったとする。
  L   1  2  3  4  5  6      ○と×では×の方が少ないので、
                            続けて×に対応する L 側の 3 と 6 について質問する。
・Lを質問(結果の一例)                        
  U  ⑫ ⑪ × ⑨ ⑧ ×      ×が1つでもあれば、|A|=6 にするために
  L   1  2 ×  3  4 ⑤      1,2,3,4 のいずれかは○でなければならない。
                            → 2が答えであることが確定する。
・Lを質問(別の結果の一例)
  U  ⑫ ⑪ × ⑨ ⑧ ×      この時点でまだ確定しないのは、
  L  × × ③ × × ⑤      全てのペアでいずれか一方のみが含まれる場合のみ

$N$ 偶数の場合も、$\frac{N}{2}$ が必ず含まれている前提で、同じことが言える。

この段階で $2$ 個は不可能。可能性のあるペアが全て潰されたので。
実は、答えは $3$ または不可能のいずれかとなる。

以下、$X,Y$ を以下のようにする。

  • $X:=U$ 側で $A$ に存在することが確定した値の集合。$N$ 偶数の場合は $\frac{N}{2}$ も含む
  • $Y:=L$ 側で $A$ に存在することが確定した値の集合

略証?

あとは「(a) $X$ から1個、$Y$ から2個」または「(b) $Y$ から3個」で $N$ を作れるかの判定問題となる。

  • $F[i]:=i$ が $Y$ に存在するなら $1$、しないなら $0$($1 \le i \lt \frac{N}{2}$)

として、$H=F \times F$ を畳み込みで計算すると、$H$ は $Y$ から2個選んだ時にその値を作れるかどうかを表す。 ただし順序付き個数である。つまり例えば $Y=\{2,4\}$ の場合、$2+4$ と $4+2$ で別に数えられるので、$H[6]=2$ となる。

同じ値を2回使うことは許されないので、$i \in Y$ に対して $H[2i]$ から $1$ ずつ減算しておく。 これで “異なる” 2個でできる和を表すようになる。

(a) は、各 $i \in X$ につき、$H[N-i] \gt 0$ なら可能と判定できる。

(b)の場合はもう少し複雑になる。
原則は $i \in Y$ に対して $H[N-i] \gt 0$ ならよいのだが、 「$N-i$ が $i$ 自身を使わないと作れない値である」(結果的に $i$ を2回使ってしまっている)可能性がある。

$N-2i \in Y$ かつ $3i \neq N$ の場合のみ、$H[N-i]-2 \gt 0$ として判定するとよい。

  • $N-2i$ が $Y$ に存在している時、$H[N-i]$ に $(i)+(N-2i)$ は $2$ だけ寄与している
  • ただし、$i=N-2i$(つまり $3i=N$)の時、$H[N-i]$ からは既に $(i)+(N-2i)$ は取り除かれている

これで(b)の場合も判定できた。

いずれの場合でも不可能なとき、最終的に不可能である。

Python3

programming_algorithm/contest_history/atcoder/2026/1025_arc233.txt · 最終更新: by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0