結果
問題 | No.449 ゆきこーだーの雨と雪 (4) |
ユーザー |
|
提出日時 | 2016-11-18 23:57:03 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 289 ms / 5,000 ms |
コード長 | 4,183 bytes |
コンパイル時間 | 1,400 ms |
コンパイル使用メモリ | 124,188 KB |
実行使用メモリ | 46,932 KB |
最終ジャッジ日時 | 2024-09-22 10:14:31 |
合計ジャッジ時間 | 11,913 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 43 |
ソースコード
#include <algorithm>#include <bitset>#include <cassert>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <deque>#include <functional>#include <iomanip>#include <iostream>#include <list>#include <map>#include <numeric>#include <queue>#include <set>#include <sstream>#include <stack>#include <string>#include <utility>#include <vector>#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);i++)using namespace std;typedef long long int ll;typedef vector<int> VI;typedef vector<ll> VL;typedef pair<int, int> PI;const ll mod = 1e9 + 7;/*** Segment Tree. This data structure is useful for fast folding on intervals of an array* whose elements are elements of monoid M. Note that constructing this tree requires the identity* element of M and the operation of M.* Header requirement: vector, algorithm* Verified by AtCoder ABC017-D (http://abc017.contest.atcoder.jp/submissions/660402)*/template<class I, class BiOp = I (*) (I, I)>class SegTree {int n;std::vector<I> dat;BiOp op;I e;public:SegTree(int n_, BiOp op, I e) : op(op), e(e) {n = 1;while (n < n_) { n *= 2; } // n is a power of 2dat.resize(2 * n);for (int i = 0; i < 2 * n - 1; i++) {dat[i] = e;}}/* ary[k] <- v */void update(int k, I v) {k += n - 1;dat[k] = v;while (k > 0) {k = (k - 1) / 2;dat[k] = op(dat[2 * k + 1], dat[2 * k + 2]);}}void update_array(int k, int len, const I *vals) {for (int i = 0; i < len; ++i) {update(k + i, vals[i]);}}/*Updates all elements. O(n)*/void update_all(const I *vals, int len) {for (int k = 0; k < std::min(n, len); ++k) {dat[k + n - 1] = vals[k];}for (int k = std::min(n, len); k < n; ++k) {dat[k + n - 1] = e;}for (int b = n / 2; b >= 1; b /= 2) {for (int k = 0; k < b; ++k) {dat[k + b - 1] = op(dat[k * 2 + b * 2 - 1], dat[k * 2 + b * 2]);}}}/* l,r are for simplicity */I querySub(int a, int b, int k, int l, int r) const {// [a,b) and [l,r) intersects?if (r <= a || b <= l) return e;if (a <= l && r <= b) return dat[k];I vl = querySub(a, b, 2 * k + 1, l, (l + r) / 2);I vr = querySub(a, b, 2 * k + 2, (l + r) / 2, r);return op(vl, vr);}/* [a, b] (note: inclusive) */I query(int a, int b) const {return querySub(a, b + 1, 0, 0, n);}};const int N = 30;int l[N];int n;map<string, int> memo;vector<string> inv;vector<VI> score;vector<int> lastmod;vector<int> sum;int get(const string &s) {if (memo.count(s)) {return memo[s];}int idx = inv.size();memo[s] = idx;inv.push_back(s);score.push_back(VI(n, 0));lastmod.push_back(0);sum.push_back(0);return idx;}int main(void){cin >> n;REP(i, 0, n) {cin >> l[i];}int t;cin >> t;VI already(n, 0);typedef pair<ll, ll> PL;vector<PL> events;VL sorter;REP(i, 0, t) {string name, p;cin >> name >> p;int v = get(name);if (p == "?") {events.push_back(PL(v, -1));continue;}int id = p[0] - 'A';int diff = l[id];already[id]++;int sc = 50 * diff + (500 * diff) / (8 + 2 * already[id]);score[v][id] = sc;lastmod[v] = i;sum[v] += sc;events.push_back(PL(v, (ll)sum[v] * 1e9 - i));sorter.push_back((ll)sum[v] * 1e9 - i);}sort(sorter.begin(), sorter.end());map<ll, int> sinv;REP(i, 0, sorter.size()) {sinv[sorter[i]] = i;}REP(i, 0, events.size()) {if (events[i].second >= 0) {events[i].second = sinv[events[i].second];}}SegTree<int, plus<int> > st(2 * t, plus<int>(), 0);VL cur(inv.size(), -1);REP(i, 0, events.size()) {int v = events[i].first;int sc = events[i].second;if (0) {cerr << "query: " << v << " " << sc << endl;}if (sc >= 0) {if (cur[v] >= 0) {st.update(cur[v], st.query(cur[v], cur[v]) - 1);}st.update(sc, st.query(sc, sc) + 1);cur[v] = sc;} else {cout << 1 + st.query(cur[v] + 1, 2 * t) << endl;}}}