Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Don’t try to count all valid choices directly. You only need to know whether the count reaches , so look for sets that are forced versus sets that can be safely toggled.
If some number appears in exactly one set, then that set must be chosen in every valid answer. There is no negotiation there; has one lifeboat.
First count how many sets contain each value . If any value appears times, there are no valid choices at all.
Call a set forced if it contains at least one value whose frequency is exactly . Every valid chosen collection must include every forced set.
The key check is: are there at least two sets that contain no uniquely occurring value? If yes, choose all sets, or omit either one of those two sets. Those are already valid ways. If fewer than two such sets exist, there can be at most ways.
We need decide whether there are at least three subsets of the given sets whose union covers every number from to .
Counting set covers in general is ugly. Luckily, the target is tiny: just distinguish from . So we should not count covers like a maniac. We only need a structural reason that gives us three valid choices.
Forced sets
For each number , let be the number of given sets containing .
If , then is impossible to cover. Answer is immediately NO.
If , then the single set containing is mandatory. Any valid selection must include it, because otherwise disappears. So every set that contains at least one uniquely appearing element is forced.
Example: if appears only in , then must be chosen. Doesn’t matter what else is happening. is not optional.
Now consider a set that contains no uniquely appearing element. Every element inside it appears somewhere else too. That means if we choose all sets and then remove this set, the union still covers everything. Every element it contributed is still covered by another set.
Call such a set optional-removable.
Why two optional-removable sets are enough
Suppose every number appears at least once, and there are two optional-removable sets, say and .
Then these three choices are all valid:
Those are three distinct valid ways. So the answer is YES.
Notice we are not even trying to be fancy and remove both. We only need three ways, and boom, done.
Why fewer than two is not enough
All forced sets must appear in every valid selection.
Only optional-removable sets can possibly vary freely. If there are:
So with fewer than two optional-removable sets, reaching three ways is impossible.
Therefore the whole problem collapses to:
NO.YES iff that count is at least .Complexity
We read and inspect every listed element a constant number of times.
The complexity is per test case, where . This fits easily inside the limits.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<vector<int>> sets(n);
vector<int> cnt(m + 1, 0);
for (int i = 0; i < n; i++) {
int l;
cin >> l;
sets[i].resize(l);
for (int &x : sets[i]) {
cin >> x;
cnt[x]++;
}
}
bool possible = true;
for (int x = 1; x <= m; x++) {
if (cnt[x] == 0) possible = false;
}
int removable = 0;
for (int i = 0; i < n; i++) {
bool forced = false;
for (int x : sets[i]) {
if (cnt[x] == 1) {
forced = true;
break;
}
}
if (!forced) removable++;
}
cout << (possible && removable >= 2 ? "YES" : "NO") << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<vector<int>> sets(n);
vector<int> cnt(m + 1, 0);
for (int i = 0; i < n; i++) {
int l;
cin >> l;
sets[i].resize(l);
for (int &x : sets[i]) {
cin >> x;
cnt[x]++;
}
}
bool possible = true;
for (int x = 1; x <= m; x++) {
if (cnt[x] == 0) possible = false;
}
int removable = 0;
for (int i = 0; i < n; i++) {
bool forced = false;
for (int x : sets[i]) {
if (cnt[x] == 1) {
forced = true;
break;
}
}
if (!forced) removable++;
}
cout << (possible && removable >= 2 ? "YES" : "NO") << '\n';
}
}