E - 通信モードの切り替え / Switching Communication Modes 解説 by admin
claude4.8opus-highSummary
This problem asks us to count the number of configurations of transmitter modes (A or B for each transmitter) such that the set of all possible XOR sums (composite signals) obtained by choosing any subset of active transmitters contains all the target signal values \(T_j\).
Analysis
XOR and Vector Spaces
The operation of “choosing some values and taking their XOR” is easier to understand if we think of it in a vector space over \(\mathrm{GF}(2)\) (the Galois field of two elements, \(0\) and \(1\)). If we view each signal value as a \(60\)-dimensional vector of \(0\)s and \(1\)s representing its bits, the XOR operation corresponds to vector addition.
Then, if we let the signal values of transmitters \(1, \dots, N\) be \(x_1, \dots, x_N\), the set of all composite signals that can be formed by choosing a subset of transmitters is exactly the linear span of \(x_1, \dots, x_N\). The empty set corresponds to \(0\).
Therefore, being able to achieve the target \(T_j\) is equivalent to “\(T_j\) being contained in this linear space.”
Conditions to Achieve All Targets
For all \(T_j\) to be contained in the span, it is sufficient and necessary that the space spanned by \(T_1, \dots, T_M\) is contained in the space spanned by \(x_1, \dots, x_N\).
The key point here is that we can reduce the target values \(T\) to a linear basis. We do not need to check all \(M\) targets individually; it is sufficient to check whether each vector in the basis constructed from \(T\) is contained in the transmitter-side span. If all vectors in the basis are contained, any \(T_j\) (which is a linear combination of these basis vectors) will automatically be contained as well.
Naive Approach and Pruning
Since \(N \le 15\), there are at most \(2^{15} = 32768\) possible mode assignments. We can easily enumerate all of them. For each assignment, we can construct the basis of the transmitter side and check if all vectors in the target basis are contained in its span.
However, the dimension of the space spanned by \(N\) vectors is at most \(N\). Therefore, if the dimension (rank) of the target basis exceeds \(N\), it is impossible to satisfy the condition under any assignment, so we can immediately return \(0\) (this is a small pruning step, but it is also useful for correctness).
Algorithm
- Construct the target basis: Build a linear basis
tbasisover \(\mathrm{GF}(2)\) from \(T_1, \dots, T_M\). This can be implemented using Gaussian elimination (maintaining a representative vector for each most significant bit (MSB) position).- If the rank of the target basis exceeds \(N\), the answer is \(0\).
- Enumerate all assignments: Try all \(2^N\) possible values of
mask. If the \(i\)-th bit ofmaskis set, transmitter \(i\) is set to mode B (value \(W_i\)); otherwise, it is set to mode A (value \(V_i\)). - Construct the transmitter basis: Construct a linear basis
basisfrom the \(N\) chosen values. - Containment check: For each vector
tvin the target basis, check if it can be reduced to \(0\) usingbasis. If we encounter an MSB for which no basis vector exists inbasisand thus cannot reduce it further, thentvis not contained in the span, and this assignment is invalid. - Count the number of assignments where all target basis vectors can be reduced to \(0\), and output the count modulo \(10^9+7\).
Process of Gaussian Elimination (Insertion and Query)
For a vector \(v\), we look at its most significant bit position \(h\). If basis[h] exists, we XOR \(v\) with it to reduce \(v\). If it does not exist, we either insert \(v\) at basis[h] (for insertion) or conclude that it cannot be reduced to \(0\) and fail (for query/containment check). We repeat this process until \(v\) becomes \(0\).
Complexity
Let the bit width be \(B=60\).
- Target basis construction: \(O(M \cdot B)\)
- Processing each assignment: \(O(N \cdot B)\) for basis construction, and \(O(\mathrm{rank} \cdot B) \le O(N \cdot B)\) for the containment check.
- Since we do this for \(2^N\) assignments, the total time for this part is \(O(2^N \cdot N \cdot B)\).
Therefore,
- Time Complexity: \(O(2^N \cdot N \cdot B + M \cdot B)\) (with \(B=60\))
- Space Complexity: \(O(B + N + M)\)
Since \(N \le 15\), \(2^N \cdot N \cdot B\) is approximately \(32768 \times 15 \times 60 \approx 3 \times 10^7\), which is well within the time limit.
Key Implementation Points
Since the signal values are at most \(2^{60}-1\), allocate the basis array with a size of \(60\). In Python, arbitrary-precision integers can be used directly, allowing for straightforward bitwise operations.
The most significant bit position can be obtained using
v.bit_length() - 1.By reducing the target side to a basis first, we can limit the number of checks to “the dimension of the basis (at most \(N\))” even if \(M\) is very large. This is the key to optimization.
Adding a pruning step to immediately return \(0\) if the rank of the target basis exceeds \(N\) allows us to handle obviously impossible cases quickly.
Since we are counting the number of valid assignments, we just need to output the count modulo \(10^9+7\) at the end (although \(2^N \le 32768\) means overflow is not an issue, we still take the modulo as specified in the problem).
Source Code
import sys
def main():
data = sys.stdin.buffer.read().split()
idx = 0
N = int(data[idx]); idx += 1
M = int(data[idx]); idx += 1
V = [0]*N
W = [0]*N
for i in range(N):
V[i] = int(data[idx]); idx += 1
W[i] = int(data[idx]); idx += 1
T = [int(data[idx+j]) for j in range(M)]
idx += M
MOD = 10**9 + 7
# target basis
tbasis = [0]*60
trank = 0
for t in T:
v = t
while v:
h = v.bit_length() - 1
bh = tbasis[h]
if bh == 0:
tbasis[h] = v
trank += 1
break
v ^= bh
if trank > N:
print(0)
return
tvecs = [x for x in tbasis if x]
count = 0
for mask in range(1 << N):
basis = [0]*60
m = mask
for i in range(N):
v = W[i] if (m >> i) & 1 else V[i]
while v:
h = v.bit_length() - 1
bh = basis[h]
if bh == 0:
basis[h] = v
break
v ^= bh
ok = True
for tv in tvecs:
v = tv
while v:
h = v.bit_length() - 1
bh = basis[h]
if bh == 0:
ok = False
break
v ^= bh
if not ok:
break
if ok:
count += 1
print(count % MOD)
main()
This editorial was generated by claude4.8opus-high.
投稿日時:
最終更新: