#include #include #include #include #include #include #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 auto vectors(T a, X x) { return vector(x, a); } template auto vectors(T a, X x, Y y, Zs... zs) { auto cont = vectors(a, y, zs...); return vector(x, cont); } 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; } }; double scoreof(int level, int solved) { assert (solved >= 1); return 50*level + 250*level/(4.0+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 vector sorted_names = sortunique(name); int m = sorted_names.size(); vector id(query); vector sorted_scores; { vector found_scores(query + 1); vector score(m); vector solved(n); repeat (t,query) { id[t] = index(sorted_names, name[t]); if (action[t] != '?') { int i = action[t] - 'A'; solved[i] += 1; score[id[t]] += scoreof(level[i], solved[i]); found_scores[t] = score[id[t]]; } } sorted_scores = sortunique(found_scores); } // answer vector solved(n); vector score(m); binary_indexed_tree bit(sorted_scores.size(), int(), plus()); bit.point_append(0, m); vector > tiebreak(sorted_scores.size()); repeat (t,query) { int j = index(sorted_scores, score[id[t]]); if (action[t] == '?') { int a = bit.initial_range_concat(j); int b = tiebreak[j].size() - (whole(find, tiebreak[j], id[t]) - 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[t])); int i = action[t] - 'A'; solved[i] += 1; score[id[t]] += scoreof(level[i], solved[i]); j = index(sorted_scores, score[id[t]]); bit.point_append(j, +1); tiebreak[j].push_back(id[t]); } } return 0; }