公式
A - 共通の好きな曲 / Common Favorite Songs 解説 by admin
Qwen3-Coder-480B概要
\(N\) 人のメンバーがそれぞれ複数の曲を選んでいるとき、全員が共通して選んでいる曲の数を求める問題。
考察
この問題では、各メンバーが選んだ曲のリストが与えられ、すべてのメンバーが選んでいる曲の集合の共通部分(積集合)を求めることになります。
素朴な方法として、例えばすべての曲に対して「その曲を何人が選んでいるか」をカウントする方法が考えられます。しかし、これには最大 \(M\) 個の曲について、それぞれ \(N\) 人を確認する必要があり、最悪ケースで \(O(N \cdot M)\) の計算量になってしまいます。制約より、これは最大で \(10^{10}\) となり、時間内に処理しきれません。
そこで効率的な方法として、「集合(set)」を使うことを考えます。最初のメンバーが選んだ曲の集合を基準とし、それに続く各メンバーの曲の集合との「共通部分(積集合)」を逐次更新していくことで、最終的に全員が選んでいる曲の集合を得ることができます。この方法では、各曲リストのサイズの合計が \(2 \times 10^5\) であることを利用して、効率的に処理できます。
アルゴリズム
- 最初のメンバーの選んだ曲の集合
common_songsを作る。 - 次のメンバー以降について、そのメンバーの選んだ曲の集合
songsを作り、common_songsとの積集合を取って更新する。 - 最終的な
common_songsの要素数を出力する。
このように集合演算を使うことで、不要な比較を避けながら効率的に共通項を求めることができます。
計算量
- 時間計算量: \(O(\sum_{i=1}^{N} K_i)\)
各メンバーの選んだ曲の数の合計だけ集合操作を行うため。 - 空間計算量: \(O(M)\)
最大で \(M\) 個の曲を格納する可能性のある集合を保持するため。
実装のポイント
- 入力を高速に読み込むために
sys.stdin.readを使用している。 - 集合の積集合演算 (
&=) を使って、共通部分を効率的に更新している。 - 最初の集合を基準にすることで、後の処理がシンプルになる。
## ソースコード
```python
import sys
from collections import defaultdict
input = sys.stdin.read
data = input().split()
idx = 0
N = int(data[idx])
idx += 1
M = int(data[idx])
idx += 1
# 最初のメンバーの曲リストを取得
k = int(data[idx])
idx += 1
common_songs = set()
for _ in range(k):
song = int(data[idx])
idx += 1
common_songs.add(song)
# 残りのメンバーの曲リストとの共通集合を取る
for i in range(1, N):
k = int(data[idx])
idx += 1
songs = set()
for _ in range(k):
song = int(data[idx])
idx += 1
songs.add(song)
common_songs &= songs
print(len(common_songs))
この解説は qwen3-coder-480b によって生成されました。
投稿日時:
最終更新: