結果
問題 | No.649 ここでちょっとQK! |
ユーザー | Fu_L |
提出日時 | 2023-07-13 13:56:02 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 581 ms / 3,000 ms |
コード長 | 5,955 bytes |
コンパイル時間 | 4,591 ms |
コンパイル使用メモリ | 275,348 KB |
実行使用メモリ | 270,212 KB |
最終ジャッジ日時 | 2024-09-15 00:38:40 |
合計ジャッジ時間 | 11,970 ms |
ジャッジサーバーID (参考情報) |
judge6 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 24 ms
5,376 KB |
testcase_04 | AC | 581 ms
270,212 KB |
testcase_05 | AC | 568 ms
265,020 KB |
testcase_06 | AC | 498 ms
252,656 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 2 ms
5,376 KB |
testcase_10 | AC | 2 ms
5,376 KB |
testcase_11 | AC | 2 ms
5,376 KB |
testcase_12 | AC | 165 ms
19,712 KB |
testcase_13 | AC | 165 ms
19,456 KB |
testcase_14 | AC | 158 ms
19,328 KB |
testcase_15 | AC | 176 ms
22,992 KB |
testcase_16 | AC | 165 ms
19,840 KB |
testcase_17 | AC | 191 ms
21,760 KB |
testcase_18 | AC | 206 ms
23,296 KB |
testcase_19 | AC | 229 ms
24,832 KB |
testcase_20 | AC | 250 ms
26,368 KB |
testcase_21 | AC | 278 ms
28,288 KB |
testcase_22 | AC | 305 ms
29,824 KB |
testcase_23 | AC | 316 ms
31,232 KB |
testcase_24 | AC | 342 ms
33,408 KB |
testcase_25 | AC | 359 ms
34,816 KB |
testcase_26 | AC | 389 ms
36,680 KB |
testcase_27 | AC | 3 ms
5,376 KB |
testcase_28 | AC | 3 ms
5,376 KB |
testcase_29 | AC | 3 ms
5,376 KB |
testcase_30 | AC | 142 ms
18,304 KB |
testcase_31 | AC | 141 ms
18,048 KB |
testcase_32 | AC | 2 ms
5,376 KB |
testcase_33 | AC | 2 ms
5,376 KB |
testcase_34 | AC | 2 ms
5,376 KB |
testcase_35 | AC | 2 ms
5,376 KB |
ソースコード
#include <bits/stdc++.h> #include <atcoder/all> using namespace std; using namespace atcoder; using ll = long long; using P = pair<ll, int>; using mint = modint998244353; #define rep(i, a, b) for(ll i = a; i < b; i++) #define rrep(i, a, b) for(ll i = a; i >= b; i--) constexpr ll inf = 4e18; using T = P; struct SelfBalancingBinarySearchTree { SelfBalancingBinarySearchTree(vector<T> vec = {}) : root(nullptr), MaxNodeCount(0) { for(T x : vec) { insert(x); } } bool find(const T& key) { return find(root, key); } int size() { return size(root); } void insert(const T& key) { insert(root, key); MaxNodeCount = max(MaxNodeCount, size(root)); } void erase(const T& key) { bool is_find = false; Node* connect = nullptr; erase(root, key, is_find, connect); if(size(root) < 0.7 * MaxNodeCount) { vector<T> value; subtree(root, value); rebuild(root, value.begin(), value.end()); MaxNodeCount = size(root); } } int lower_bound(const T& key) { return lower_bound(root, key); } int upper_bound(const T& key) { return upper_bound(root, key); } T get(int idx) { return get(root, idx); } private: struct Node { T key; int count = 1; Node* child[2] = {nullptr, nullptr}; Node(const T& val) : key(val) {} }; Node* root; int MaxNodeCount; bool find(Node* cur, const T& key) const { while(cur) { if(key == cur->key) return true; else if(key < cur->key) cur = cur->child[0]; else cur = cur->child[1]; } return false; } inline int size(Node*& cur) const { if(!cur) return 0; return cur->count; } void insert(Node*& cur, const T& key) { if(!cur) { cur = new Node(key); } else if(key < cur->key) { insert(cur->child[0], key); } else if(key > cur->key) { insert(cur->child[1], key); } cur->count = size(cur->child[0]) + size(cur->child[1]) + 1; if(size(cur->child[0]) > 0.7 * size(cur) or size(cur->child[1]) > 0.7 * size(cur)) { vector<T> value; subtree(cur, value); rebuild(cur, value.begin(), value.end()); } } void erase(Node*& cur, const T& key, bool& is_find, Node*& connect) { if(!cur) { return; } else if(key < cur->key) { erase(cur->child[0], key, is_find, connect); if(is_find) { Node* tmp = cur->child[0]; cur->child[0] = connect; delete tmp; is_find = false; connect = nullptr; } } else if(key > cur->key) { erase(cur->child[1], key, is_find, connect); if(is_find) { Node* tmp = cur->child[1]; cur->child[1] = connect; delete tmp; is_find = false; connect = nullptr; } } else { if(cur->child[0] and cur->child[1]) { T nex_key = get(upper_bound(key)); erase(root, nex_key, is_find, connect); cur->key = nex_key; } else { if(cur->child[0]) connect = cur->child[0]; else if(cur->child[1]) connect = cur->child[1]; is_find = true; if(cur == root) { root = connect; is_find = false; connect = nullptr; return; } } } cur->count = size(cur->child[0]) + size(cur->child[1]) + 1; return; } int lower_bound(Node*& cur, const T& key) const { if(!cur) return 0; if(key == cur->key) return size(cur->child[0]); if(key < cur->key) return lower_bound(cur->child[0], key); else return size(cur->child[0]) + lower_bound(cur->child[1], key) + 1; } int upper_bound(Node*& cur, const T& key) const { if(!cur) return 0; if(key == cur->key) return size(cur->child[0]) + 1; if(key < cur->key) return upper_bound(cur->child[0], key); else return size(cur->child[0]) + upper_bound(cur->child[1], key) + 1; } T get(Node*& cur, int idx) const { assert(0 <= idx and idx < size(cur)); if(idx == size(cur->child[0])) return cur->key; else if(idx < size(cur->child[0])) return get(cur->child[0], idx); else return get(cur->child[1], idx - size(cur->child[0]) - 1); } using Iter = vector<T>::iterator; void rebuild(Node*& cur, Iter begin, Iter end) { int Size = int(end - begin); if(Size == 0) { cur = nullptr; return; } Iter mid = begin + Size / 2; cur = new Node(*mid); rebuild(cur->child[0], begin, mid); rebuild(cur->child[1], mid + 1, end); cur->count = size(cur->child[0]) + size(cur->child[1]) + 1; } void subtree(Node*& cur, vector<T>& val) const { if(!cur) return; subtree(cur->child[0], val); val.push_back(cur->key); subtree(cur->child[1], val); } }; int main(void) { cin.tie(0); ios::sync_with_stdio(0); int Q, K; cin >> Q >> K; SelfBalancingBinarySearchTree tree; map<ll, int> mp; while(Q--) { int t; cin >> t; if(t == 1) { ll v; cin >> v; mp[v]++; tree.insert(P(v, mp[v])); } else { if((int)tree.size() < K) { cout << -1 << '\n'; } else { P ans = tree.get(K - 1); cout << ans.first << '\n'; tree.erase(ans); } } } }