結果
| 問題 |
No.649 ここでちょっとQK!
|
| コンテスト | |
| ユーザー |
kazuma
|
| 提出日時 | 2018-04-03 22:15:40 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 217 ms / 3,000 ms |
| コード長 | 4,447 bytes |
| コンパイル時間 | 2,152 ms |
| コンパイル使用メモリ | 195,476 KB |
| 最終ジャッジ日時 | 2025-01-05 09:53:33 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 32 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <typename T>
class red_black_tree {
using COL = bool;
const static COL RED = false, BLACK = true;
struct node {
COL color;
int size;
T val;
node *p, *ch[2];
node() : color(BLACK), size(0), val(), p(nullptr), ch{ nullptr, nullptr } {}
node(COL c, T v, node *par, node *l, node *r) : color(c), size(1), val(v), p(par), ch{ l, r } {}
} *NIL, *root;
node* new_node(T val) {
return new node(RED, val, NIL, NIL, NIL);
}
void update(node *x) {
x->size = x->ch[0]->size + 1 + x->ch[1]->size;
}
void update_up(node *x) {
while (x != NIL) update(x), x = x->p;
}
void rotate(node *x, int b) {
node *y = x->ch[1 - b];
x->ch[1 - b] = y->ch[b];
if (y->ch[b] != NIL) {
y->ch[b]->p = x;
}
y->p = x->p;
if (x->p == NIL) {
root = y;
}
else {
x->p->ch[x != x->p->ch[0]] = y;
}
y->ch[b] = x;
x->p = y;
update(x);
update(y);
}
void insert_fix(node *x) {
while (x->p->color == RED) {
int b = (x->p != x->p->p->ch[0]);
node *y = x->p->p->ch[1 - b];
if (y->color == RED) {
x->p->color = BLACK;
y->color = BLACK;
x->p->p->color = RED;
x = x->p->p;
continue;
}
if (x == x->p->ch[1 - b]) {
x = x->p;
rotate(x, b);
}
x->p->color = BLACK;
x->p->p->color = RED;
rotate(x->p->p, 1 - b);
}
root->color = BLACK;
}
void transplant(node *u, node *v) {
if (u->p == NIL) {
root = v;
}
else {
u->p->ch[u != u->p->ch[0]] = v;
}
v->p = u->p;
}
void erase_fix(node *x) {
while (x != root && x->color == BLACK) {
int b = (x != x->p->ch[0]);
node *w = x->p->ch[1 - b];
if (w->color == RED) {
w->color = BLACK;
x->p->color = RED;
rotate(x->p, b);
w = x->p->ch[1 - b];
}
if (w->ch[b]->color == BLACK && w->ch[1 - b]->color == BLACK) {
w->color = RED;
x = x->p;
continue;
}
if (w->ch[1 - b]->color == BLACK) {
w->ch[b]->color = BLACK;
w->color = RED;
rotate(w, 1 - b);
w = x->p->ch[1 - b];
}
w->color = x->p->color;
x->p->color = BLACK;
w->ch[1 - b]->color = BLACK;
rotate(x->p, b);
x = root;
}
x->color = BLACK;
}
node* find_first(node *x) {
if (x == NIL) return NIL;
while (x->ch[0] != NIL) x = x->ch[0];
return x;
}
node* find(node *t, int k) {
if (k < 0 || t->size <= k) return NIL;
node *x = t;
while (x->ch[0]->size != k) {
if (k < x->ch[0]->size) {
x = x->ch[0];
}
else {
k -= x->ch[0]->size + 1;
x = x->ch[1];
}
}
return x;
}
public:
red_black_tree() : NIL(new node()), root(NIL) {}
int size() {
return root->size;
}
T find(int k) {
return find(root, k)->val;
}
void update(int k, T val) {
node *t = find(root, k);
t->val = val;
}
int count_lower(T val) {
node *t = root;
int res = 0;
while (t != NIL) {
if (t->val == val) return res + t->ch[0]->size;
if (t->val < val) {
res += t->ch[0]->size + 1;
t = t->ch[1];
}
else {
t = t->ch[0];
}
}
return res;
}
void insert(int k, T val) {
node *y = NIL, *v = new_node(val);
if (root == NIL) {
root = v;
}
else if (k == 0) {
y = find_first(root);
y->ch[0] = v;
}
else {
y = find(root, k - 1);
if (y->ch[1] == NIL) {
y->ch[1] = v;
}
else {
y = find_first(y->ch[1]);
y->ch[0] = v;
}
}
v->p = y;
update_up(y);
insert_fix(v);
}
void erase(int k) {
node *x = find(root, k);
erase(x);
}
void erase(node *x) {
if (x == NIL) return;
node *y = x, *z;
COL c = y->color;
if (x->ch[0] == NIL) {
z = x->ch[1];
transplant(x, x->ch[1]);
}
else if (x->ch[1] == NIL) {
z = x->ch[0];
transplant(x, x->ch[0]);
}
else {
y = find_first(x->ch[1]);
c = y->color;
z = y->ch[1];
if (y->p == x) {
z->p = y;
}
else {
transplant(y, y->ch[1]);
y->ch[1] = x->ch[1];
y->ch[1]->p = y;
}
transplant(x, y);
y->ch[0] = x->ch[0];
y->ch[0]->p = y;
y->color = x->color;
update(y);
}
update_up(z->p);
if (c == BLACK) erase_fix(z);
}
};
int main()
{
ios::sync_with_stdio(false), cin.tie(0);
int Q, K;
cin >> Q >> K;
red_black_tree<ll> tree;
while (Q--) {
int t;
cin >> t;
if (t == 1) {
ll v;
cin >> v;
tree.insert(tree.count_lower(v), v);
}
else if (tree.size() >= K) {
printf("%lld\n", tree.find(K - 1));
tree.erase(K - 1);
}
else {
printf("%d\n", -1);
}
}
return 0;
}
kazuma