#include #include #include #include #include #include using namespace std; const int degree = 3; struct BPlusTreeNode { int keys[degree]; int count[degree + 1]; int total; BPlusTreeNode* pointers[degree + 1]; bool is_leaf; int size; BPlusTreeNode() { for (int i = 0; i < degree; i++) keys[i] = 0; for (int i = 0; i <= degree; i++) count[i] = 0; for (int i = 0; i <= degree; i++) pointers[i] = NULL; total = 0; is_leaf = 0; size = 0; } BPlusTreeNode* insert_key(int key) { if (is_leaf) return insert_key_to_leaf(key); return insert_key_to_node(key); } BPlusTreeNode* insert_key_to_node(int key) { assert(!is_leaf); int pos = size; while (pos > 0 && keys[pos - 1] > key) pos--; total -= count[pos]; BPlusTreeNode* ret = pointers[pos]->insert_key(key); count[pos] = pointers[pos]->total; total += count[pos]; if (ret == NULL) return NULL; return insert_node_to_node(pos, ret); } BPlusTreeNode* insert_node_to_node(int index, BPlusTreeNode *node) { assert(!is_leaf); if (size < degree) { insert_node_to_node_no_split(index, node); return NULL; } return insert_node_to_node_split(index, node); } BPlusTreeNode* insert_node_to_node_split(int index, BPlusTreeNode *node) { assert(!is_leaf); assert(size == degree); BPlusTreeNode* right = new BPlusTreeNode(); bool node_inserted = 0; int pos = size; while (pos >= 0 && (right->size + 1) < (degree + 2) / 2) { if (pos == index && !node_inserted) { right->insert_node_to_node_head(node); node_inserted = 1; continue; } right->insert_node_to_node_head(pointers[pos]); delete_last_node_from_node(); pos--; } if (!node_inserted) insert_node_to_node_no_split(index, node); return right; } void insert_node_to_node_no_split(int index, BPlusTreeNode *node) { assert(!is_leaf); assert(size < degree); for (int i = size ; i > index; i--) { keys[i] = keys[i - 1]; count[i + 1] = count[i]; pointers[i + 1] = pointers[i]; } keys[index] = node->minimum_key(); count[index + 1] = node->total; total += count[index + 1]; pointers[index + 1] = node; size++; } void insert_node_to_node_head(BPlusTreeNode *node) { assert(!is_leaf); assert(size < degree); for (int i = size; i >= 0; i--) { count[i + 1] = count[i]; pointers[i + 1] = pointers[i]; } for (int i = size; i > 0; i--) keys[i] = keys[i - 1]; if (pointers[1] != NULL) { keys[0] = pointers[1]->minimum_key(); size++; } count[0] = node->total; total += count[0]; pointers[0] = node; } BPlusTreeNode* insert_key_to_leaf(int key) { assert(is_leaf); if (size < degree) { insert_key_to_leaf_no_split(key); return NULL; } return insert_key_to_leaf_split(key); } BPlusTreeNode* insert_key_to_leaf_split(int key) { assert(is_leaf); assert(size == degree); BPlusTreeNode* right = new BPlusTreeNode(); right->is_leaf = 1; bool key_inserted = 0; int pos = size - 1; while (pos >= 0 && (right->size) < (degree + 1) / 2) { if (keys[pos] < key && !key_inserted) { right->insert_key_to_leaf_no_split(key); key_inserted = 1; continue; } right->insert_key_to_leaf_no_split(keys[pos]); delete_last_key_from_leaf(); pos--; } if (!key_inserted) insert_key_to_leaf_no_split(key); right->pointers[degree] = pointers[degree]; if (pointers[degree] != NULL) pointers[degree]->pointers[0] = right; pointers[degree] = right; right->pointers[0] = this; return right; } void insert_key_to_leaf_no_split(int key) { assert(is_leaf); assert(size < degree); int pos = size; while (pos > 0 && keys[pos - 1] > key) { keys[pos] = keys[pos - 1]; pos--; } keys[pos] = key; total++; size++; } void delete_key(int key) { if (is_leaf) delete_key_from_leaf(key); else delete_key_from_node(key); } void delete_key_from_node(int key) { assert(!is_leaf); int pos = size; while (pos > 0 && keys[pos - 1] > key) pos--; total--; count[pos]--; pointers[pos]->delete_key(key); if (pointers[pos]->is_leaf) fix_leaf(pos); else fix_node(pos); } void fix_leaf(int index) { assert(pointers[index]->is_leaf); if (pointers[index]->size >= (degree + 1) / 2) { count[index] = pointers[index]->total; if (index > 0) keys[index - 1] = pointers[index]->minimum_key(); return; } if (index > 0 && pointers[index - 1]->size > (degree + 1) / 2) { // 左隣から借りる BPlusTreeNode* left = pointers[index - 1]; pointers[index]->insert_key_to_leaf_no_split(left->keys[left->size - 1]); left->delete_last_key_from_leaf(); count[index]++; count[index - 1]--; keys[index - 1] = pointers[index]->minimum_key(); return; } if (index < size && pointers[index + 1]->size >(degree + 1) / 2) { // 右隣から借りる BPlusTreeNode* right = pointers[index + 1]; pointers[index]->insert_key_to_leaf_no_split(right->keys[0]); right->delete_first_key_from_leaf(); count[index]++; count[index + 1]--; keys[index] = right->minimum_key(); return; } if (index > 0) { // 左隣とマージする BPlusTreeNode* left = pointers[index - 1]; while (pointers[index]->size > 0) { left->insert_key_to_leaf_no_split(pointers[index]->keys[pointers[index]->size - 1]); pointers[index]->delete_last_key_from_leaf(); } count[index - 1] = pointers[index - 1]->total; if (pointers[index]->pointers[degree] != NULL) pointers[index]->pointers[degree]->pointers[0] = pointers[index - 1]; pointers[index - 1]->pointers[degree] = pointers[index]->pointers[degree]; for (int i = index; i + 1 <= size; i++) { keys[i - 1] = keys[i]; count[i] = count[i + 1]; pointers[i] = pointers[i + 1]; } if (index > 1) keys[index - 2] = left->minimum_key(); keys[size - 1] = 0; count[size] = 0; pointers[size] = NULL; size--; return; } // 右隣とマージする(index = 0の場合のみ) BPlusTreeNode* right = pointers[index + 1]; while (pointers[index]->size > 0) { right->insert_key_to_leaf_no_split(pointers[index]->keys[pointers[index]->size - 1]); pointers[index]->delete_last_key_from_leaf(); } count[index + 1] = pointers[index + 1]->total; if (pointers[index]->pointers[0] != NULL) pointers[index]->pointers[0]->pointers[degree] = pointers[index + 1]; pointers[index + 1]->pointers[0] = pointers[index]->pointers[0]; for (int i = index; i + 1 <= size; i++) { keys[i - 1] = keys[i]; count[i] = count[i + 1]; pointers[i] = pointers[i + 1]; } keys[size - 1] = 0; count[size] = 0; pointers[size] = NULL; size--; } void fix_node(int index) { assert(!pointers[index]->is_leaf); if (pointers[index]->size + 1 >= (degree + 2) / 2) { count[index] = pointers[index]->total; if (index > 0) keys[index - 1] = pointers[index]->minimum_key(); return; } if (index > 0 && pointers[index - 1]->size + 1 > (degree + 2) / 2) { // 左隣から借りる BPlusTreeNode* left = pointers[index - 1]; pointers[index]->insert_node_to_node_head(left->pointers[left->size]); left->delete_last_node_from_node(); count[index - 1] = left->total; count[index] = pointers[index]->total; keys[index - 1] = pointers[index]->minimum_key(); return; } if (index < size && pointers[index + 1]->size + 1 >(degree + 2) / 2) { // 右隣から借りる BPlusTreeNode* right = pointers[index + 1]; pointers[index]->insert_node_to_node_no_split(pointers[index]->size, right->pointers[0]); right->delete_first_node_from_node(); count[index + 1] = right ->total; count[index] = pointers[index]->total; keys[index] = right ->minimum_key(); return; } if (index > 0) { // 左隣とマージする BPlusTreeNode* left = pointers[index - 1]; while (pointers[index]->size >= 0) { left->insert_node_to_node(left->size, pointers[index]->pointers[0]); if(pointers[index]->size > 0) pointers[index]->delete_first_node_from_node(); else break; } count[index - 1] = pointers[index - 1]->total; for (int i = index; i + 1 <= size; i++) { keys[i - 1] = keys[i]; count[i] = count[i + 1]; pointers[i] = pointers[i + 1]; } if (index > 1) keys[index - 2] = left->minimum_key(); keys[size - 1] = 0; count[size] = 0; pointers[size] = NULL; size--; return; } // 右隣とマージする(index = 0の場合のみ) BPlusTreeNode* right = pointers[index + 1]; while(pointers[index]->size >= 0) { right->insert_node_to_node_head(pointers[index]->pointers[pointers[index]->size]); if (pointers[index]->size > 0) pointers[index]->delete_last_node_from_node(); else break; } count[index + 1] = pointers[index + 1]->total; for (int i = index; i + 1 <= size; i++) { keys[i - 1] = keys[i]; count[i] = count[i + 1]; pointers[i] = pointers[i + 1]; } keys[size - 1] = 0; count[size] = 0; pointers[size] = NULL; size--; } void delete_key_from_leaf(int key) { assert(is_leaf); int pos = 0; while (pos < size) { if (keys[pos] == key) break; pos++; } assert(pos < size); for (int i = pos; i + 1 < size; i++) keys[i] = keys[i + 1]; keys[size - 1] = 0; total--; size--; } void delete_last_key_from_leaf() { assert(is_leaf); assert(size > 0); keys[size - 1] = 0; total--; size--; } void delete_first_key_from_leaf() { assert(is_leaf); assert(size > 0); for (int i = 1; i < size; i++) keys[i - 1] = keys[i]; keys[size - 1] = 0; total--; size--; } void delete_last_node_from_node() { assert(!is_leaf); assert(size > 0); keys[size - 1] = 0; pointers[size] = NULL; total -= count[size]; count[size] = 0; size--; } void delete_first_node_from_node() { assert(!is_leaf); assert(size > 0); total -= count[0]; for (int i = 1; i < size; i++) keys[i - 1] = keys[i]; for (int i = 1; i <= size; i++) { count[i - 1] = count[i]; pointers[i - 1] = pointers[i]; } keys[size - 1] = 0; count[0] = 0; pointers[size] = NULL; size--; } int minimum_key() { if (is_leaf) { assert(size > 0); return keys[0]; } assert(pointers[0] != NULL); return pointers[0]->minimum_key(); } }; struct BPlusTree { BPlusTreeNode* root; BPlusTree() { root = new BPlusTreeNode(); root->is_leaf = 1; } void insert_key(int key) { BPlusTreeNode* ret = root->insert_key(key); if (ret != NULL) { BPlusTreeNode* new_root = new BPlusTreeNode(); new_root->insert_node_to_node_head(root); new_root->insert_node_to_node_no_split(0, ret); root = new_root; } } void delete_key(int key) { root->delete_key(key); if (root->size == 0 && !root->is_leaf) root = root->pointers[0]; } std::pair find(int key) { BPlusTreeNode* now = root; while (!now->is_leaf) { int pos = now->size; while (pos > 0 && now->keys[pos - 1] > key) pos--; now = now->pointers[pos]; } bool is_included = 0; for (int i = 0; i < now->size; i++) { if (now->keys[i] == key) return std::make_pair(now, i); } return std::make_pair((BPlusTreeNode*) NULL, -1); } // 0-indexed int get_kth(int k) { BPlusTreeNode* now = root; while (!now->is_leaf) { int pos = 0; int sum = 0; while (pos < now->size && (sum + now->count[pos]) <= k) { sum += now->count[pos]; pos++; } now = now->pointers[pos]; k -= sum; } return now->keys[k]; } int size() { return root->total; } }; /*int main() { int Q; scanf("%d", &Q); BPlusTree btree; for (int i = 0; i < Q; i++) { int T, X; scanf("%d %d", &T, &X); if (T == 1) { btree.insert_key(X); } else { X--; int v = btree.get_kth(X); printf("%d\n", v); btree.delete_key(v); } } }*/ int main() { int Q, K; scanf("%d %d", &Q, &K); vector> query; vector vec; for (int i = 0; i < Q; i++) { int t; scanf("%d", &t); if (t == 1) { long long v; scanf("%lld", &v); query.emplace_back(1, v); vec.push_back(v); } else { query.emplace_back(2, -1); } } sort(vec.begin(), vec.end()); vec.erase(unique(vec.begin(), vec.end()), vec.end()); BPlusTree btree; for (int i = 0; i < Q; i++) { if (query[i].first == 1) { int idx = lower_bound(vec.begin(), vec.end(), query[i].second) - vec.begin(); btree.insert_key(idx); } else { if (btree.size() < K) { printf("-1\n"); continue; } int idx = btree.get_kth(K - 1); printf("%lld\n", vec[idx]); btree.delete_key(idx); } } }