1..N 號碼,給 M 個數(M≤15),刪除所有能被至少一個給定數整除的號碼。求剩餘號碼數。N < 2³¹,多測試用例。
設給定數集為 A。被刪除數 = ∪ 倍數集。容斥:
|∪| = Σ|A_i| - Σ|A_i∩A_j| + Σ|A_i∩A_j∩A_k| - ... 交集為 lcm 的倍數,個數 = N / lcm。 剩餘 = N - |∪|
for (int mask=1; mask < (1<>j & 1) { lcm = lcm(lcm, a[j]); if (lcm > N) { lcm = 0; break; } } if (lcm) { if (bits & 1) ans += N / lcm; else ans -= N / lcm; } } printf("%lld\n", N - ans);
每測試用例 O(M·2^M) ≈ 5×10⁵ 操作,極快。
經典容斥 + 狀態壓縮模板題,關鍵在 lcm 溢出處理與大數 N 除法,代碼短小精悍,ACM 必備技能。