D - ウイルス検査と感染端末 / Virus Testing and Infected Terminals 解説 by admin
GPT 5.2 HighOverview
Assuming each terminal is either “infected” or “not infected,” we find the assignment that is consistent with all scan results (1 if the scanned set contains at least one infected terminal, 0 otherwise) and minimizes the number of infected terminals.
Analysis
The key insight of this problem is that all conditions on terminal sets can be expressed as “whether the intersection of the set and the infected set is empty or not.”
Scan result \(R_j = 0\) (no infection)
→ The set \(S_j\) examined by this scan contains no infected terminals at all
→ For the infected set \(X\): \(X \cap S_j = \emptyset\)
→ In other words, all terminals in \(S_j\) are confirmed to be non-infected.Scan result \(R_j = 1\) (infection found)
→ The set \(S_j\) contains at least one infected terminal
→ \(X \cap S_j \neq \emptyset\)
Since the constraint \(N \le 16\) is small, we can exhaustively search all possible infected terminal sets \(X\) (\(2^N\) possibilities).
A naive “enumerate all and check all conditions” approach is fast enough, but we can speed it up further with the following:
- Process all \(R_j=0\) conditions together and immediately exclude terminals from infection candidates (powerful pruning)
- Skip candidates with infection count greater than or equal to the current minimum (best) (count-based pruning)
- Represent sets as bitmasks for fast intersection checks (
x & mask)
Algorithm
Using bitmasks, we represent the infected terminal set \(X\) as an integer from \(0\) to \((1<<N)-1\) (bit \(i\) is 1 if terminal \(i\) is infected).
- Read input and convert each scan’s target set to a bitmask
mask. - For scans with \(R=0\):
- Since the set contains no infected terminals, accumulate the entire set into
must_zerousing OR. - Terminals whose bits are set in
must_zerocannot be infected.
- Since the set contains no infected terminals, accumulate the entire set into
- For scans with \(R=1\):
- The condition “\(X \cap S_j \neq \emptyset\)” must be satisfied, so save
maskintor1_masks.
- The condition “\(X \cap S_j \neq \emptyset\)” must be satisfied, so save
- Enumerate all \(X\) (\(0 \le X < 2^N\)) and find the one with the minimum infection count that satisfies:
(X & must_zero) == 0(no terminal marked as non-infectable is infected)- For all
m in r1_masks:(X & m) != 0(intersects with each “infection found” set)
Count the number of infected terminals using popcount (in Python, bit_count()), and update the minimum.
Complexity
- Time complexity: \(O(2^N \cdot M)\)
(Since \(N \le 16\), there are at most \(2^{16}=65536\) candidates, and each candidate checks at most \(M\) conditions) - Space complexity: \(O(M)\)
(For storing the scan sets with \(R=1\), plus a constant number of variables)
Implementation Notes
Terminal numbers in the input are \(1\)-indexed, so subtract \(1\) before setting the bit with
1 << s.By consolidating \(R=0\) conditions into
must_zero, during enumeration a single check(X & must_zero)suffices to eliminate invalid candidates, which is fast.Candidates with infection count greater than or equal to the already found minimum
bestare unnecessary, so we prune afterbit_count().Intersection checks are done simply by checking whether
X & maskis 0 or not, which is significantly faster than storing sets as lists.Source Code
import sys
def main():
it = iter(map(int, sys.stdin.buffer.read().split()))
N = next(it)
M = next(it)
must_zero = 0
r1_masks = []
for _ in range(M):
K = next(it)
mask = 0
for _ in range(K):
s = next(it) - 1
mask |= 1 << s
r = next(it)
if r == 0:
must_zero |= mask
else:
r1_masks.append(mask)
best = N + 1
for x in range(1 << N):
if x & must_zero:
continue
bc = x.bit_count()
if bc >= best:
continue
ok = True
for m in r1_masks:
if (x & m) == 0:
ok = False
break
if ok:
best = bc
if best == 0:
break
print(best)
if __name__ == "__main__":
main()
This editorial was generated by gpt-5.2-high.
投稿日時:
最終更新: