Problem Info
My Work
#include <iostream>
#include <cassert>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include "debugging.h"
using std::cout;
using std::endl;
using std::vector;
// https://codeforces.com/problemset/problem/1017/D (sample input ommitted due to length)
int main() {
int str_len;
int set_size;
int query_num;
std::cin >> str_len >> set_size >> query_num;
vector<int> values(str_len);
for (int& v : values) {
std::cin >> v;
}
std::reverse(values.begin(), values.end());
vector<int> set_buckets(1 << str_len);
for (int i = 0; i < set_size; i++) {
std::string val;
std::cin >> val;
assert(val.length() == str_len);
set_buckets[std::stoi(val, nullptr, 2)]++;
}
vector<std::map<int, int>> cached_results(1 << str_len);
for (int q = 0; q < query_num; q++) {
std::string query_str;
int max_val;
std::cin >> query_str >> max_val;
assert(query_str.length() == str_len);
int query = std::stoi(query_str, nullptr, 2);
std::map<int, int>& wu_vals = cached_results[query];
if (wu_vals.empty()) {
for (int i = 0; i < (1 << str_len); i++) {
if (set_buckets[i] == 0) {
continue;
}
int wu_val = 0;
for (int at = 0; at < str_len; at++) {
wu_val += (((query >> at) & 1) == ((i >> at) & 1)) * values[at];
}
wu_vals[wu_val] += set_buckets[i];
}
int prev_amt = 0;
for (auto it = wu_vals.begin(); it != wu_vals.end(); it++) {
it->second += prev_amt;
prev_amt = it->second;
}
}
if (max_val < wu_vals.begin()->first) {
cout << 0 << '\n';
} else {
auto it = wu_vals.lower_bound(max_val);
if (it == wu_vals.end()) {
it--;
}
cout << it->second << '\n';
}
}
}
It basically processes the queries online, catching the Wu values when operated with each of the personal treasure pieces.
However, this TLEs on test case #4.
What I’ve Tried
I can’t download the test data (because it’s CF), and I don’t really know how to write my own. It should meet the complexity constraints- it’s somewhere around 2^{24}, right?