#include #include #include #include #include #include #define repeat(i,n) for (int i = 0; (i) < (n); ++(i)) #define whole(f,x,...) ([&](decltype((x)) whole) { return (f)(begin(whole), end(whole), ## __VA_ARGS__); })(x) using namespace std; template T sortunique(T xs) { whole(sort, xs); xs.erase(whole(unique, xs), xs.end()); return xs; } template int index(vector const & xs, T x) { return whole(lower_bound, xs, x) - xs.begin(); } template struct binary_indexed_tree { // on monoid vector data; T unit; function append; // associative template binary_indexed_tree(size_t n, T a_unit, F a_append) : data(n, a_unit), unit(a_unit), append(a_append) {} void point_append(size_t i, T w) { // data[i] += w for (size_t j = i+1; j <= data.size(); j += j & -j) data[j-1] = append(data[j-1], w); } int initial_range_concat(size_t i) { // sum [0, i) T acc = unit; for (size_t j = i; 0 < j; j -= j & -j) acc = append(acc, data[j-1]); return acc; } }; int scoreof(int level, int solved) { assert (solved >= 1); return 50*level + 250*level/(4+solved); } int main() { // input int n; cin >> n; vector level(n); repeat (i,n) cin >> level[i]; int query; cin >> query; vector name(query); vector action(query); repeat (t,query) cin >> name[t] >> action[t]; // prepare const int max_score = 100 * whole(accumulate, level, 0); vector ids = sortunique(name); int m = ids.size(); // answer vector solved(n); vector score(m); binary_indexed_tree bit(max_score + 1, int(), plus()); bit.point_append(0, m); vector > tiebreak(max_score + 1); repeat (t,query) { int id = index(ids, name[t]); int j = score[id]; if (action[t] == '?') { int a = bit.initial_range_concat(j); int b = tiebreak[j].size() - (whole(find, tiebreak[j], id) - tiebreak[j].begin()) - 1; cout << m-a-b << endl; } else { bit.point_append(j, -1); if (j) tiebreak[j].erase(whole(find, tiebreak[j], id)); int i = action[t] - 'A'; solved[i] += 1; j = score[id] += scoreof(level[i], solved[i]); bit.point_append(j, +1); tiebreak[j].push_back(id); } } return 0; }