結果
| 問題 |
No.649 ここでちょっとQK!
|
| コンテスト | |
| ユーザー |
nok0
|
| 提出日時 | 2020-12-20 23:39:51 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 145 ms / 3,000 ms |
| コード長 | 3,328 bytes |
| コンパイル時間 | 1,800 ms |
| コンパイル使用メモリ | 197,288 KB |
| 最終ジャッジ日時 | 2025-01-17 05:09:40 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 32 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:143:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
143 | scanf("%d%d", &q, &k);
| ~~~~~^~~~~~~~~~~~~~~~
main.cpp:148:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
148 | scanf("%d", &type);
| ~~~~~^~~~~~~~~~~~~
main.cpp:150:30: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
150 | scanf("%lld", &x);
| ~~~~~^~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
template <typename T>
struct treap {
private:
struct xorshift {
using u32 = uint32_t;
u32 x = 123456789, y = 362436069, z = 521288629, w = 88675123;
xorshift(u32 seed = 0) { z ^= seed; }
u32 operator()() {
u32 t = x ^ (x << 11);
x = y;
y = z;
z = w;
return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}
};
xorshift rnd;
struct Node {
T key;
int pri, cnt;
Node *l, *r;
Node(T key_, int pri_) : key(key_), pri(pri_), cnt(1), l(nullptr), r(nullptr) {}
} *root = nullptr;
using Tree = Node *;
int count(Tree t) { return t ? t->cnt : 0; }
void update_cnt(Tree &t) {
if(t) t->cnt = 1 + count(t->l) + count(t->r);
}
void split(Tree t, T key, Tree &l, Tree &r) {
if(!t)
l = r = nullptr;
else if(key < t->key)
split(t->l, key, l, t->l), r = t, update_cnt(r);
else
split(t->r, key, t->r, r), l = t, update_cnt(l);
}
void merge(Tree &t, Tree l, Tree r) {
if(!l or !r)
t = l ? l : r;
else if(l->pri > r->pri)
merge(l->r, l->r, r), t = l, update_cnt(t);
else
merge(r->l, l, r->l), t = r, update_cnt(t);
}
void insert(Tree &t, Tree item) {
if(!t)
t = item;
else if(item->pri > t->pri)
split(t, item->key, item->l, item->r), t = item, update_cnt(t);
else
insert(item->key < t->key ? t->l : t->r, item), update_cnt(t);
}
void erase(Tree &t, T key) {
if(t->key == key)
merge(t, t->l, t->r);
else
erase(key < t->key ? t->l : t->r, key), update_cnt(t);
}
bool find(Tree &t, T key) {
if(!t)
return false;
else if(t->key == key)
return true;
else
return find(key < t->key ? t->l : t->r, key);
}
Tree lower_bound(Tree &t, T key) {
if(!t)
return nullptr;
else if(t->key >= key) {
Tree res = lower_bound(t->l, key);
return res == nullptr ? t : res;
} else
return lower_bound(t->r, key);
}
Tree upper_bound(Tree &t, T key) {
if(!t)
return nullptr;
else if(t->key > key) {
Tree res = upper_bound(t->l, key);
return res == nullptr ? t : res;
} else
return upper_bound(t->r, key);
}
Tree kth_element(Tree &t, int cnt) {
if(!t) return nullptr;
int sum = count(t->l) + 1;
return (cnt < sum ? kth_element(t->l, cnt) : (sum == cnt ? t : kth_element(t->r, cnt - sum)));
}
void dump(Tree &t) {
if(!t) return;
dump(t->l);
std::cout << t->key << " ";
dump(t->r);
}
public:
void insert(const T key) {
// if it is set, use ↓
// if(find(key)) return;
insert(root, new Node(key, rnd()));
}
void erase(const T key) { erase(root, key); }
bool find(const T key) { return find(root, key); }
Tree lower_bound(const T key) { return lower_bound(root, key); }
Tree upper_bound(const T key) { return upper_bound(root, key); }
//0_indexed
T kth_element(const int cnt) {
assert(root and 0 <= cnt and cnt < root->cnt);
return kth_element(root, cnt + 1)->key;
}
int size() {
return root ? root->cnt : 0;
}
void dump() {
dump(root);
std::cout << "\n";
}
};
int q, k, type;
long long x;
int main() {
scanf("%d%d", &q, &k);
treap<long long> set;
while(q--) {
scanf("%d", &type);
if(type == 1) {
scanf("%lld", &x);
set.insert(x);
}
if(type == 2) {
if(set.size() < k)
puts("-1");
else {
long long res = set.kth_element(k - 1);
printf("%lld\n", res);
set.erase(res);
}
}
}
return 0;
}
nok0