結果

問題 No.649 ここでちょっとQK!
ユーザー Div9851Div9851
提出日時 2020-01-31 22:58:36
言語 C++11
(gcc 11.4.0)
結果
RE  
実行時間 -
コード長 12,479 bytes
コンパイル時間 798 ms
コンパイル使用メモリ 59,888 KB
実行使用メモリ 23,184 KB
最終ジャッジ日時 2023-10-17 11:47:25
合計ジャッジ時間 7,730 ms
ジャッジサーバーID
(参考情報)
judge14 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,348 KB
testcase_01 AC 1 ms
4,348 KB
testcase_02 AC 2 ms
4,348 KB
testcase_03 AC 28 ms
7,224 KB
testcase_04 AC 128 ms
23,184 KB
testcase_05 AC 103 ms
19,224 KB
testcase_06 AC 91 ms
19,164 KB
testcase_07 AC 1 ms
4,348 KB
testcase_08 AC 2 ms
4,348 KB
testcase_09 AC 2 ms
4,348 KB
testcase_10 AC 1 ms
4,348 KB
testcase_11 AC 2 ms
4,348 KB
testcase_12 RE -
testcase_13 RE -
testcase_14 RE -
testcase_15 RE -
testcase_16 AC 82 ms
9,788 KB
testcase_17 AC 92 ms
10,316 KB
testcase_18 AC 102 ms
11,108 KB
testcase_19 AC 113 ms
11,636 KB
testcase_20 AC 122 ms
12,528 KB
testcase_21 AC 131 ms
13,056 KB
testcase_22 AC 142 ms
13,584 KB
testcase_23 AC 153 ms
14,376 KB
testcase_24 AC 165 ms
15,168 KB
testcase_25 AC 178 ms
15,696 KB
testcase_26 WA -
testcase_27 AC 2 ms
4,348 KB
testcase_28 AC 2 ms
4,348 KB
testcase_29 AC 2 ms
4,348 KB
testcase_30 RE -
testcase_31 RE -
testcase_32 AC 2 ms
4,348 KB
testcase_33 AC 1 ms
4,348 KB
testcase_34 AC 2 ms
4,348 KB
testcase_35 AC 1 ms
4,348 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:443:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  443 |         scanf("%d %d", &Q, &K);
      |         ~~~~~^~~~~~~~~~~~~~~~~
main.cpp:448:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  448 |                 scanf("%d", &t);
      |                 ~~~~~^~~~~~~~~~
main.cpp:451:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  451 |                         scanf("%lld", &v);
      |                         ~~~~~^~~~~~~~~~~~

ソースコード

diff #

#include <cstdio>
#include <cassert>
#include <climits>
#include <utility>
#include <vector>
#include <algorithm>
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<BPlusTreeNode*, int> 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<pair<int, long long>> query;
	vector<long long> 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);
		}
	}
}
0