E - 通信モードの切り替え / Switching Communication Modes 解説 by admin
gemini-3.5-flash-highOverview
This problem asks us to find the number of assignments of transmitter modes (A or B) out of \(2^N\) possible assignments such that all \(M\) given target signal values can be represented as the XOR (exclusive OR) sum of the output values of a subset of the selected transmitters.
Analysis
1. Focusing on Constraints
Notice that the number of transmitters \(N\) is extremely small, being at most \(15\). Since each transmitter has \(2\) modes, A and B, there are only \(2^N \le 2^{15} = 32,768\) possible assignment patterns in total. Therefore, an approach that performs an exhaustive search (brute-force) over all assignments and checks whether each satisfies the condition is effective.
2. Checking Representability by XOR Sum (Linear Basis)
Once a mode assignment is fixed, resulting in a set of transmitter output values \(X = \{X_1, X_2, \dots, X_N\}\), we need to quickly check whether each target signal value \(T_j\) can be represented as the XOR sum of a subset of \(X\).
This can be viewed as a problem in vector spaces (linear algebra) over \(\mathbb{F}_2\), where XOR is treated as addition. By constructing a linear basis from the set \(X\), we can check whether any number \(T_j\) can be represented as the XOR sum of elements in \(X\) in \(O(\log(\max T_j))\) time.
3. Optimization by Simplifying Target Signal Values
If we naively check whether all target signal values \(T_1, T_2, \dots, T_M\) can be represented, we would need to perform \(M\) checks for each assignment. To speed up this check, we can precompute the linear basis \(T_{\text{basis}}\) of the set of target signal values \(T\) itself. The statement “all elements in \(T\) can be represented” is equivalent to “all elements in the linear basis of \(T\) can be represented”. Since the size of the basis of \(T\) is at most the number of bits (at most \(60\) in this case), we can significantly reduce the number of checks.
Algorithm
Constructing the Basis of Target Signal Values From the input \(M\) target signal values \(T_1, \dots, T_M\), construct a linear basis
target_basisusing Gaussian elimination. If the size oftarget_basisis larger than the number of transmitters \(N\), it is impossible to represent them no matter how we choose the modes. Thus, we can immediately output0and terminate (early return).Exhaustive Search of Assignments Iterate through the integers
maskfrom \(0\) to \(2^N - 1\). If the \(i\)-th bit ofmaskis0, set the mode of transmitter \(i\) to A (value \(V_i\)); if it is1, set it to B (value \(W_i\)). This determines the set of output values \(X\) for each transmitter.Constructing the Basis of Transmitter Outputs From the determined elements of \(X\), construct a linear basis
basisin the same way using Gaussian elimination.Checking Representability For each element \(t\) in
target_basis, check if it can be represented usingbasis. Specifically, iterating from the most significant bit (MSB) of \(t\) downwards, if there is an element inbasiswith the same MSB, we XOR \(t\) with that element. If \(t\) eventually becomes \(0\), it is representable. If all elements intarget_basisare representable, themasksatisfies the condition, so we increment the answer count by \(1\).Output Output the final count modulo \(10^9 + 7\).
Complexity
Time Complexity: \(O(M \log(\max T) + 2^N \cdot N \log(\max V))\)
- Constructing the basis of target signal values takes \(O(M \log(\max T))\) time.
- In the search over all assignments (\(2^N\) iterations), constructing the transmitter basis takes \(O(N \log(\max V))\) time, and checking representability takes \(O(B \log(\max V))\) time (where \(B\) is the size of
target_basis, with \(B \le N\)). - Since \(N \le 15\) and \(\log(\max V) \le 60\), even in the worst case, the number of operations inside the loop is around \(3.2 \times 10^4 \times 15 \times 60 \approx 2.9 \times 10^7\) basic operations, which easily fits within the time limit (usually 2 seconds).
Space Complexity: \(O(N + M + \log(\max T))\)
- It is extremely memory-efficient as it only uses arrays to store the bases and input data.
Implementation Points
Leveraging
std::bit_widthBy usingstd::bit_widthintroduced in C++20, we can quickly obtain the position of the most significant bit (MSB) of a number (i.e., its bit length in binary). This allows us to write the Gaussian elimination process in a simple and fast manner.Early Return If the size of the basis of target signal values exceeds \(N\), it is absolutely impossible to represent them due to an insufficient number of transmitters. Thus, we can avoid unnecessary computations by outputting \(0\) and terminating before starting the search.
Source Code
#include <iostream>
#include <vector>
#include <bit>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N, M;
if (!(cin >> N >> M)) return 0;
vector<long long> V(N), W(N);
for (int i = 0; i < N; ++i) {
cin >> V[i] >> W[i];
}
vector<long long> T(M);
for (int j = 0; j < M; ++j) {
cin >> T[j];
}
vector<long long> t_basis(61, 0);
for (int j = 0; j < M; ++j) {
long long x = T[j];
while (x > 0) {
int bit = std::bit_width(static_cast<unsigned long long>(x)) - 1;
if (!t_basis[bit]) {
t_basis[bit] = x;
break;
}
x ^= t_basis[bit];
}
}
vector<long long> target_basis;
for (int bit = 60; bit >= 0; --bit) {
if (t_basis[bit]) {
target_basis.push_back(t_basis[bit]);
}
}
if (target_basis.size() > N) {
cout << 0 << "\n";
return 0;
}
long long ans = 0;
vector<long long> X(N);
vector<long long> basis(61);
vector<pair<int, long long>> basis_list;
basis_list.reserve(N);
for (int mask = 0; mask < (1 << N); ++mask) {
for (int i = 0; i < N; ++i) {
X[i] = (mask & (1 << i)) ? W[i] : V[i];
}
fill(basis.begin(), basis.end(), 0);
for (int i = 0; i < N; ++i) {
long long x = X[i];
while (x > 0) {
int bit = std::bit_width(static_cast<unsigned long long>(x)) - 1;
if (!basis[bit]) {
basis[bit] = x;
break;
}
x ^= basis[bit];
}
}
basis_list.clear();
for (int bit = 60; bit >= 0; --bit) {
if (basis[bit]) {
basis_list.push_back({bit, basis[bit]});
}
}
bool ok = true;
for (long long t : target_basis) {
for (auto [bit, val] : basis_list) {
if ((t >> bit) & 1) {
t ^= val;
}
}
if (t != 0) {
ok = false;
break;
}
}
if (ok) {
ans++;
}
}
cout << ans % 1000000007 << "\n";
return 0;
}
This editorial was generated by gemini-3.5-flash-high.
投稿日時:
最終更新: