結果
問題 | No.618 labo-index |
ユーザー |
|
提出日時 | 2018-01-14 18:12:41 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 412 ms / 6,000 ms |
コード長 | 6,162 bytes |
コンパイル時間 | 1,255 ms |
コンパイル使用メモリ | 111,832 KB |
実行使用メモリ | 7,072 KB |
最終ジャッジ日時 | 2024-12-24 02:55:15 |
合計ジャッジ時間 | 8,616 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 35 |
ソースコード
#define _USE_MATH_DEFINES#include <cstdio>#include <iostream>#include <sstream>#include <fstream>#include <iomanip>#include <algorithm>#include <cmath>#include <complex>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <set>#include <map>#include <bitset>#include <numeric>#include <limits>#include <climits>#include <cfloat>#include <functional>#include <iterator>using namespace std;unsigned xorshift(){static unsigned x=123456789, y=362436069, z=521288629, w=88675123;unsigned t=(x^(x<<11));x=y; y=z; z=w;return w=(w^(w>>19))^(t^(t>>8));}template <class T>class Treap{private:class Node{public:T val;int left, right;int num;unsigned priority;Node(T val){this->val = val;left = -1;right = -1;num = 1;priority = xorshift();}};vector<Node> nodes;queue<int> q;int root;// 部分木のノード個数を更新するvoid updateNum(int curr){nodes[curr].num = 1;if(nodes[curr].left != -1)nodes[curr].num += nodes[nodes[curr].left].num;if(nodes[curr].right != -1)nodes[curr].num += nodes[nodes[curr].right].num;}// 木の回転処理int rotate(int curr, bool isLeftUp){int next;if(isLeftUp){next = nodes[curr].left;nodes[curr].left = nodes[next].right;nodes[next].right = curr;}else{next = nodes[curr].right;nodes[curr].right = nodes[next].left;nodes[next].left = curr;}updateNum(curr);updateNum(next);return next;}// 部分木に要素xを追加int insert(int curr, const T& x){if(curr == -1){if(q.empty()){nodes.push_back(Node(x));return nodes.size() - 1;}else{int i = q.front();q.pop();nodes[i] = Node(x);return i;}}if(x < nodes[curr].val){int next = insert(nodes[curr].left, x);nodes[curr].left = next;updateNum(curr);if(nodes[nodes[curr].left].priority < nodes[curr].priority)curr = rotate(curr, true);}else{int next = insert(nodes[curr].right, x);nodes[curr].right = next;updateNum(curr);if(nodes[nodes[curr].right].priority < nodes[curr].priority)curr = rotate(curr, false);}return curr;}// 部分木から要素xを削除(要素xが存在しなければ何もしない)int erase(int curr, const T& x){if(curr == -1)return -1;if(nodes[curr].val == x){if(nodes[curr].left == -1 && nodes[curr].right == -1){q.push(curr);return -1;}if(nodes[curr].right == -1 || (nodes[curr].left != -1 && nodes[nodes[curr].left].priority < nodes[nodes[curr].right].priority)){curr = rotate(curr, true);nodes[curr].right = erase(nodes[curr].right, x);}else{curr = rotate(curr, false);nodes[curr].left = erase(nodes[curr].left, x);}}else{if(x < nodes[curr].val)nodes[curr].left = erase(nodes[curr].left, x);elsenodes[curr].right = erase(nodes[curr].right, x);}updateNum(curr);return curr;}// 部分木のi番目の要素を返すconst T& at(int curr, int i){if(nodes[curr].left != -1){if(i < nodes[nodes[curr].left].num)return at(nodes[curr].left, i);i -= nodes[nodes[curr].left].num;}if(i == 0)return nodes[curr].val;elsereturn at(nodes[curr].right, i-1);}// 部分木からx未満の値を持つ要素の個数を返すint getLowerNum(int curr, const T& x){if(curr == -1)return 0;int ans = 0;if(nodes[curr].val < x){if(nodes[curr].left != -1)ans += nodes[nodes[curr].left].num;ans += getLowerNum(nodes[curr].right, x) + 1;}else{ans += getLowerNum(nodes[curr].left, x);}return ans;}public:Treap(){root = -1;}// 要素xを追加void insert(const T& x){root = insert(root, x);}// 要素xを削除void erase(const T& x){root = erase(root, x);}// 要素の個数を返すint size(){if(root == -1)return 0;elsereturn nodes[root].num;}// i番目の要素を返すconst T& operator[](int i){return at(root, i);}// x未満の値を持つ要素の個数を返すint getLowerNum(const T& x){return getLowerNum(root, x);}// 区間[x,y)の値を持つ要素の個数を返すint getRangeNum(const T& x, const T& y){return getLowerNum(root, y) - getLowerNum(root, x);}};int main(){int q;cin >> q;vector<long long> v;Treap<long long> t;long long offset = 0;while(--q >= 0){int type;long long x;cin >> type >> x;if(type == 1){v.push_back(x - offset);t.insert(x - offset);}else if(type == 2){t.erase(v[x-1]);}else{offset += x;}int n = t.size();int left = 0;int right = n;while(left < right){int mid = (left + right) / 2;if(n - mid <= t[mid] + offset)right = mid;elseleft = mid + 1;}cout << (n - left) << endl;}return 0;}