結果
| 問題 | No.649 ここでちょっとQK! |
| コンテスト | |
| ユーザー |
Fu_L
|
| 提出日時 | 2023-07-13 13:56:02 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 532 ms / 3,000 ms |
| コード長 | 5,955 bytes |
| 記録 | |
| コンパイル時間 | 3,994 ms |
| コンパイル使用メモリ | 261,780 KB |
| 最終ジャッジ日時 | 2025-02-15 10:11:01 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 32 |
ソースコード
#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);
}
}
}
}
Fu_L