結果
| 問題 | No.649 ここでちょっとQK! |
| コンテスト | |
| ユーザー |
akakimidori
|
| 提出日時 | 2018-12-09 02:32:43 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 7,943 bytes |
| 記録 | |
| コンパイル時間 | 500 ms |
| コンパイル使用メモリ | 32,356 KB |
| 実行使用メモリ | 14,336 KB |
| 最終ジャッジ日時 | 2024-09-15 07:54:32 |
| 合計ジャッジ時間 | 4,245 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 11 WA * 21 |
ソースコード
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
typedef struct AVLNode {
short rank;
short bias;
size_t size;
struct AVLNode *parent;
struct AVLNode *left;
struct AVLNode *right;
unsigned long long int val[];
} node;
node* newNode (const void *val, const size_t size) {
node *r = (node *) malloc (sizeof (node) + size);
r -> rank = 1;
r -> bias = 0;
r -> size = 1;
r -> parent = NULL;
r -> left = NULL;
r -> right = NULL;
memcpy (r -> val, val, size);
return r;
}
short getRank (const node *t) {
return t == NULL ? 0 : t -> rank;
}
short getBias (const node *t) {
return t == NULL ? 0 : t -> bias;
}
int getSize (const node *t) {
return t == NULL ? 0 : t -> size;
}
void update (node *t) {
short lrank = getRank (t -> left);
short rrank = getRank (t -> right);
t -> rank = (lrank > rrank ? lrank : rrank) + 1;
t -> bias = lrank - rrank;
t -> size = getSize (t -> left) + getSize (t -> right) + 1;
}
int isLeftChild (const node *t) {
return t != NULL && t -> parent != NULL && t -> parent -> left == t;
}
void concatL (node *parent, node *child) {
if(child != NULL) {
child -> parent = parent;
}
if(parent != NULL) {
parent -> left = child;
}
}
void concatR (node *parent, node *child) {
if(child != NULL) {
child -> parent = parent;
}
if(parent != NULL) {
parent -> right = child;
}
}
node* rightRotate (node *v) {
assert(v !=NULL && v -> left != NULL);
node *u = v -> left;
concatL (v, u -> right);
if (isLeftChild (v)) {
concatL (v -> parent, u);
} else {
concatR (v -> parent, u);
}
concatR (u, v);
update (v);
update (u);
return u;
}
node* leftRotate (node *u) {
assert(u !=NULL && u -> right != NULL);
node *v = u -> right;
concatR (u, v -> left);
if (isLeftChild (u)) {
concatL (u -> parent, v);
} else {
concatR (u -> parent, v);
}
concatL (v, u);
update (u);
update (v);
return v;
}
node* balance (node *t) {
const short b = getBias (t);
if (-1 <= b && b <= 1) {
return t;
}
if (b < -1) {
if (getBias (t -> right) >= 1) {
rightRotate (t -> right);
}
return leftRotate (t);
} else {
if(getBias (t -> left) <= -1){
leftRotate (t -> left);
}
return rightRotate (t);
}
}
node* saveTree (node *t) {
node *now = t;
node *before = NULL;
while (now != NULL) {
update (now);
before = balance (now);
now = before -> parent;
}
return before;
}
typedef struct MultiSet_AVL {
node *root;
size_t valSize;
int (*cmp) (const void *, const void *);
} multiset;
multiset* newMultiSet (const size_t size, int (*cmp) (const void *, const void *)) {
multiset *mset = (multiset *)malloc(sizeof (multiset));
mset -> root = NULL;
mset -> valSize = size;
mset -> cmp = cmp;
return mset;
}
int getSetSize (const multiset *set) {
return getSize (set -> root);
}
node* getMaxRef (const multiset *set) {
if (set -> root == NULL) {
return NULL;
}
node *now = set -> root;
while (now -> right != NULL) {
now = now -> right;
}
return now;
}
node* getMinRef (multiset *set) {
if (set -> root == NULL) {
return NULL;
}
node *now = set -> root;
while (now -> left != NULL) {
now = now -> left;
}
return now;
}
node* getAtRef (multiset *set, int k) {
if (k <= 0 || getSetSize (set) < k) {
return NULL;
}
node *now = set -> root;
while (1) {
int lSize = getSize (now -> left);
if (k == lSize + 1){
return now;
}
if (k <= lSize) {
now = now -> left;
} else {
k -= lSize + 1;
now = now -> right;
}
}
}
node* nextRef(node *t){
if (t -> right != NULL) {
node *s = t -> right;
while (s -> left != NULL) {
s = s-> left;
}
return s;
}
node *now = t -> parent;
node *before = t;
while (now != NULL && now -> left != before) {
before = now;
now = now -> parent;
}
return now;
}
node* prevRef(node *t){
if (t -> left != NULL) {
node *s = t -> left;
while (s -> right != NULL) {
s = s-> right;
}
return s;
}
node *now = t -> parent;
node *before = t;
while (now != NULL && now -> right != before) {
before = now;
now = now -> parent;
}
return now;
}
node* insert (multiset *set, const void *val) {
node * const in = newNode (val, set -> valSize);
if (set -> root == NULL) {
set -> root = in;
return in;
}
int (*cmp) (const void *, const void *) = set -> cmp;
node *before = NULL;
node *now = set -> root;
int cmpRes = 0;
while (now != NULL) {
before = now;
cmpRes = cmp (in -> val, now -> val);
now = cmpRes <= 0 ? now -> left : now -> right;
}
if (cmpRes <= 0) {
concatL (before, in);
} else {
concatR (before, in);
}
set -> root = saveTree (before);
return in;
}
void eraseByRef (multiset *set, node *t) {
if (t == NULL) {
return;
}
if (t -> left == NULL && t -> right == NULL) {
if (t -> parent == NULL) {
set -> root = NULL;
free (t);
return;
} else {
node *p = t -> parent;
if (isLeftChild (t)) {
p -> left = NULL;
} else {
p -> right = NULL;
}
free (t);
set -> root = saveTree (p);
}
} else if (t -> left == NULL) {
node *p = t -> parent;
if (isLeftChild (t)){
concatL (p, t -> right);
} else {
concatR (p, t -> right);
}
free (t);
set -> root = saveTree (p);
} else if (t -> right == NULL) {
node *p = t -> parent;
if (isLeftChild (t)){
concatL (p, t -> left);
} else {
concatR (p, t -> left);
}
free (t);
set -> root = saveTree (p);
} else {
node *max = t -> left;
while (max -> right != NULL) {
max = max -> right;
}
if (max -> parent == t) {
if (isLeftChild (t)) {
concatL (t -> parent, max);
} else {
concatR (t -> parent, max);
}
concatR (max, t -> right);
set -> root = saveTree (max);
} else {
if (max -> left == NULL){
max -> parent -> right = NULL;
} else {
concatR (max -> parent, max -> right);
}
node *p = t -> left;
p -> parent = NULL;
p = saveTree(max -> parent);
concatL (max, p);
if (isLeftChild (t)) {
concatL (t -> parent, max);
} else {
concatR (t -> parent, max);
}
concatR (max, t -> right);
set -> root = saveTree(max);
free (t);
}
}
}
void eraseAt (multiset *set, const int k) {
if (k < 1 || getSize (set -> root) < k) {
return;
}
eraseByRef (set, getAtRef (set, k));
}
typedef long long int int64;
void print_rec(node *p){
if(p==NULL){
printf("Nil");
return;
}
putchar('(');
print_rec(p->left);
putchar(',');
printf("%lld",*(int64 *)p->val);
putchar(',');
print_rec(p->right);
putchar(')');
}
void printSet(multiset *set){
printf("set :");
node *now = getMinRef(set);
while(now!=NULL){
printf(" %lld",*(int64 *)now->val);
now=nextRef(now);
}
printf("\n");
printf("rev :");
now = getMaxRef(set);
while(now!=NULL){
printf(" %lld",*(int64 *)now->val);
now=prevRef(now);
}
printf("\n");
printf("rec :");
print_rec(set->root);
printf("\n");
return;
}
int cmp(const void *a,const void *b){
int64 p=*(int64 *)a;
int64 q=*(int64 *)b;
return p==q?0:p-q<0?-1:1;
}
void run(void){
int q,k;
scanf("%d%d",&q,&k);
multiset *set=newMultiSet(sizeof(int64),cmp);
while(q--){
//assert(set->root==NULL || set->root->parent==NULL);
//printf("size : %d\n",getSetSize(set));
//printSet(set);
int c;
scanf("%d",&c);
if(c==1){
int64 v;
scanf("%lld",&v);
insert(set,&v);
} else if(getSetSize(set)<k){
printf("-1\n");
} else {
node *p=getAtRef(set,k);
int64 v=*(int64 *)p->val;
eraseByRef(set, p);
printf("%lld\n",v);
}
}
}
int main(void){
run();
return 0;
}
akakimidori