#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") #include using namespace std; using ll = long long; using Key = unsigned __int128; using SignedKey = __int128; constexpr int BITS = 19; // N <= 300000. constexpr int PERSON[6][2] = {{0, -1}, {1, -1}, {2, -1}, {0, 1}, {0, 2}, {1, 2}}; constexpr Key STEP[6] = {Key(1) << (BITS * 5), Key(1) << (BITS * 4), Key(1) << (BITS * 3), Key(1) << (BITS * 2), Key(1) << BITS, Key(1)}; struct State { Key key = 0; ll score = 0; }; struct Pattern { array delta{}; array used_delta{}; SignedKey key_delta = 0; array changed{}; uint8_t changed_size = 0; }; vector make_patterns() { set> unique; array delta{}; auto add = [&](auto&& self, int left, int first) -> void { if (!left) { unique.insert(delta); return; } for (int t = first; t < 6; ++t) { ++delta[t]; self(self, left - 1, t); --delta[t]; } }; auto remove = [&](auto&& self, int left, int first, int to_add) -> void { if (!left) { add(add, to_add, 0); return; } for (int t = first; t < 6; ++t) { --delta[t]; self(self, left - 1, t, to_add); ++delta[t]; } }; for (int r = 0; r <= 2; ++r) remove(remove, r, 0, r + 1); vector patterns; patterns.reserve(unique.size()); for (auto d : unique) { Pattern p; p.delta = d; for (int t = 0; t < 6; ++t) { if (!d[t]) continue; p.changed[p.changed_size++] = t; p.key_delta += SignedKey(STEP[t]) * d[t]; p.used_delta[PERSON[t][0]] += d[t]; if (PERSON[t][1] != -1) p.used_delta[PERSON[t][1]] += d[t]; } patterns.push_back(p); } return patterns; } void solve(const vector& patterns) { int n; array stamina; cin >> n >> stamina[0] >> stamina[1] >> stamina[2]; array, 6> value; for (int i = 0; i < n; ++i) { int t; ll v; cin >> t >> v; value[t - 1].push_back(v); } array sizes; array, 6> prefix; for (int t = 0; t < 6; ++t) { auto& v = value[t]; sort(v.rbegin(), v.rend()); sizes[t] = v.size(); prefix[t].resize(v.size() + 1); for (size_t j = 0; j < v.size(); ++j) prefix[t][j + 1] = prefix[t][j] + v[j]; } array count{}; array used{}; State current; vector answer; for (int depth = 1; depth <= n; ++depth) { State next; bool found = false; for (const Pattern& p : patterns) { bool valid = true; for (int i = 0; i < 3; ++i) { int x = used[i] + p.used_delta[i]; if (x < 0 || x > stamina[i]) { valid = false; break; } } if (!valid) continue; ll score = current.score; for (int j = 0; j < p.changed_size; ++j) { int t = p.changed[j]; int after = count[t] + p.delta[t]; if (after < 0 || after > sizes[t]) { valid = false; break; } score += prefix[t][after] - prefix[t][count[t]]; } if (!valid) continue; Key key = Key(SignedKey(current.key) + p.key_delta); if (!found || score > next.score || (score == next.score && key < next.key)) { next = {key, score}; found = true; } } if (!found) break; current = next; for (int t = 0; t < 6; ++t) count[t] = int((current.key >> (BITS * (5 - t))) & ((Key(1) << BITS) - 1)); used[0] = count[0] + count[3] + count[4]; used[1] = count[1] + count[3] + count[5]; used[2] = count[2] + count[4] + count[5]; answer.push_back(current.score); } cout << answer.size(); for (ll x : answer) cout << ' ' << x; cout << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); const vector patterns = make_patterns(); int test_cases; cin >> test_cases; while (test_cases--) solve(patterns); }