Problem:
Binary Search Tree III
Write a program which performs the following operations to a binary search tree $T$ by adding delete operation to B: Binary Search Tree II.
insert
$k$: Insert a node containing $k$ as key into $T$.
find
$k$: Report whether $T$ has a node containing $k$.
delete
$k$: Delete a node containing $k$.
print
: Print the keys of the binary search tree by inorder tree walk and  preorder tree walk respectively.
The operation delete $k$ for deleting a given node $z$ containing key $k$ from $T$ can be implemented by an algorithm which considers the following cases:
If $z$ has no children, we modify its parent $z.p$ to replace $z$ with NIL as its child (delete $z$).
If $z$ has only a single child, we "splice out" $z$ by making a new link between its child and its parent.
If $z$ has two children, we splice out $z$'s successor $y$ and replace $z$'s key with $y$'s key.
Input
In the first line, the number of operations $m$ is given. In the following $m$ lines, operations represented by
insert
$k$,
find
$k$,
delete
$k$ or
print
are given.
Output
For each
find
$k$ operation, print "
yes
" if $T$ has a node containing $k$, "
no
" if not.
In addition, for each
print
operation, print a list of keys obtained by inorder tree walk and preorder tree walk in a line respectively. Put a space character
before each key
Constraints
The number of operations $\leq 500,000$
The number of print operations $\leq 10$.
$-2,000,000,000 \leq key \leq 2,000,000,000$
The height of the binary tree does not exceed 100 if you employ the above pseudo code.
The keys in the binary search tree are all different.
Sample Input 1
18
insert 8
insert 2
insert 3
insert 7
insert 22
insert 1
find 1
find 2
find 3
find 4
find 5
find 6
find 7
find 8
print
delete 3
delete 7
print
Sample Output 1
yes
yes
yes
no
no
no
yes
yes
 1 2 3 7 8 22
 8 2 1 3 7 22
 1 2 8 22
 8 2 1 22
Reference
Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, s, n) for (int i = (s); i < (n); i++)


// vectorを出力する
void vecprint(vector<int> vec) {
    rep(i, vec.size()) {
        cout << vec[i] << endl;
    }
}
void newvecprint(vector<int> vec) {
    rep(i, vec.size()) {
        cout << vec[i] << " ";
    }
    cout << endl;
}

// 最大か最小を求める
int minval(vector<int> vec) {
    return *min_element(begin(vec), end(vec));
}
int maxval(vector<int> vec) {
    return *max_element(begin(vec), end(vec));
}

struct node {
    int key;
    node *right, *left, *parent;
};

node *root, *NIL;

void insert(int k) {
    node *y = NIL;
    node *x = root;
    node *z;

    z = (node *)malloc(sizeof(node));
    z->key = k;
    z->left = NIL;
    z->right = NIL;

    while (x != NIL) {
        y = x;
        if (z->key < x->key) {
            x = x->left;
        } else {
            x = x->right;
        }
    }
    z->parent = y;
    if (y == NIL) {
        root = z;
    } else {
        if (z->key < y->key) {
            y->left = z;
        } else {
            y->right = z;
        }
    }
}

node* getMinimum(node *x) {
    while (x->left != NIL) {
        x = x->left;
    }
    return x;
}

node* getSuccessor(node *x) {
    if (x->right != NIL) {
        return getMinimum(x->right);
    }
    node *y = x->parent;
    while (y != NIL && x == y->parent) {
        x = y;
        y = y->parent;
    }
    return y;
}

void tree_delete(node *z) {
    node *y;
    node *x;
    if (z->left == NIL || z->right == NIL) {
        y = z;
    }
    else {
        y = getSuccessor(z);
    }

    if (y->left != NIL) {
        x = y->left;
    }
    else {
        x = y->right;
    }
    if (x != NIL) {
        x->parent = y->parent;
    }
    if (y->parent == NIL) {
        root = x;
    }
    else {
        if (y == y->parent->left) {
            y->parent->left = x;
        }
        else {
            y->parent->right = x;
        }
    }
    if (y != z) {
        z->key = y->key;
    }
    free(y);
}

node* find(int k) {
    node *x = root;
    while (x != NIL && k != x->key) {
        if (k < x->key) {
            x = x->left;
        }
        else {
            x = x->right;
        }
    }
    return x;
}

void inorder(node *u) {
    if (u == NIL) {
        return;
    }
    inorder(u->left);
    cout << " " << u->key;
    inorder(u->right);
}
void preorder(node *u) {
    if (u == NIL) {
        return;
    }
    cout << " " << u->key;
    preorder(u->left);
    preorder(u->right);
}

void solve() {
    ll n;
    cin >> n;
    rep(i, n) {
        string cmd;
        cin >> cmd;
        if (cmd == "insert") {
            ll target;
            cin >> target;
            insert(target);
        }
        else if (cmd == "print") {
            inorder(root);
            cout << endl;
            preorder(root);
            cout << endl;
        }
        else if (cmd == "find") {
            ll target;
            cin >> target;
            node* t = find(target);
            if (t != NIL) {
                cout << "yes" << endl;
            }
            else cout << "no" << endl;
        }
        else if (cmd == "delete") {
            ll target;
            cin >> target;
            tree_delete(find(target));
        }
    }

    return;
}

int main() {
    solve();
    return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 22272
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct binary_node
{
    int id;
    binary_node* parent;
    binary_node* left;
    binary_node* right;
    bool disposed;

    int key;

    void set_left(binary_node& l)
    {
        left = &l;
    }
    void set_right(binary_node& r)
    {
        right = &r;
    }
    binary_node(int i, int k)
    {
        id = i;
        key = k;
        parent = nullptr;
        left = nullptr;
        right = nullptr;
        disposed = false;
    }
    binary_node() : binary_node(-1, -2147483648) {}
};

struct binary_tree
{
    vector<binary_node> nodes;
    binary_node* root;
    int node_count;

    void insert(int k)
    {
        binary_node* z = &nodes[node_count];
        z->key = k;
        node_count++;

        binary_node* y = nullptr;
        binary_node* x = this->root;
        while(x != nullptr)
        {
            y = x;
            if(z->key < x->key)
                x = x->left;
            else
                x = x->right;
        }

        if(y == nullptr)
        {
            root = z;
        }
        else
        {
            z->parent = y;
            if(z->key < y->key)
                y->left = z;
            else
                y->right = z;
        }
    }

    bool find(int k)
    {
        if(node_count == 0)
            return false;
        else
        {
            binary_node* x = root;
            while(x != nullptr)
            {
                if(k == x->key && !x->disposed)
                    return true;

                if(k < x->key)
                    x = x->left;
                else
                    x = x->right;
            }
            return false;
        }
    }
    
    void del(binary_node* z)
    {
        z->disposed = true;
        if(z->left == nullptr && z->right == nullptr)
        {
            if(z->key < z->parent->key)
                z->parent->left = nullptr;
            else
                z->parent->right = nullptr;
        }
        else if(z->left != nullptr && z->right == nullptr)
        {
            if(z->key < z->parent->key)
            {
                z->parent->left = z->left;
                z->left->parent = z->parent;
            }
            else
            {
                z->parent->right = z->left;
                z->left->parent = z->parent;
            }
        }
        else if(z->left == nullptr && z->right != nullptr)
        {
            if(z->key < z->parent->key)
            {
                z->parent->left = z->right;
                z->right->parent = z->parent;
            }
            else
            {
                z->parent->right = z->right;
                z->right->parent = z->parent;
            }
        }
        else
        {
            z->disposed = false;
            // successor（右部分木の最小ノード）を探す
            binary_node* y = z->right;
            while (y->left != nullptr)
                y = y->left;

            z->key = y->key; // 値をコピー
            del(y);          // successorを削除
        }
    }
    void del(int k)
    {
        //キーの位置の節点を探す
        if(node_count == 0)
            return;
        else
        {
            binary_node* x = root;
            while(true)
            {
                if(x == nullptr)
                    return;

                if(k == x->key)
                {
                    del(x);
                    return; 
                }

                if(k < x->key)
                    x = x->left;
                else
                    x = x->right;
            }
        }
    }

    void preorder_walk(binary_node* n)
    {
        if(n->disposed == false)
            cout << " " << n->key;
        if(n->left != nullptr)
            preorder_walk(n->left);
        if(n->right != nullptr)
            preorder_walk(n->right);
    }
    void preorder_walk()
    {
        preorder_walk(root);
        cout << endl;
    }
    void inorder_walk(binary_node* n)
    {
        if(n->left != nullptr)
            inorder_walk(n->left);
        if(n->disposed == false)
            cout << " " << n->key;
        if(n->right != nullptr)
            inorder_walk(n->right);
    }
    void inorder_walk()
    {
        inorder_walk(root);
        cout << endl;
    }

    binary_tree(int n)
    {
        node_count = 0;
        root = nullptr;
        for(int i = 0; i < n; i++)
            nodes.push_back(binary_node(i,-2147483648));
    }
    binary_tree() : binary_tree(0) {};
};

int main()
{
    int q;
    cin >> q;

    binary_tree t = binary_tree(q);

    for(int query = 0; query < q; query++)
    {
        string s;
        cin >> s;
        if(s == "insert")
        {
            int k;
            cin >> k;
            t.insert(k);
        }
        if(s == "find")
        {
            int k;
            cin >> k;
            if(t.find(k))
                cout << "yes" << endl;
            else
                cout << "no" << endl;
        }
        if(s == "delete")
        {
            int k;
            cin >> k;
            t.del(k);
        }
        if(s == "print")
        {
            t.inorder_walk();
            t.preorder_walk();
        }
    }
}
accuracy: 1
time_ms: 390
memory_kb: 23940
final_rank: 19

code_snippet: #include <iostream>
#include <string>
#include <cstdio>
using namespace std;

struct Node {
    int key;
    Node *right, *left, *parent;
};

Node *root, *NIL;

Node* treeMinimum(Node *x) {
    while (x->left != NIL) x = x->left;
    return x;
}

Node* find(Node *u, int k) {
    while (u != NIL && k != u->key) {
        if (k < u->key) u = u->left;
        else u = u->right;
    }
    return u;
}

Node* treeSuccessor(Node *x) {
    if (x->right != NIL) return treeMinimum(x->right);
    Node *y = x->parent;
    while (y != NIL && x == y->right) {
        x = y;
        y = y->parent;
    }
    return y;
}

void treeDelete(Node *z) {
    Node *y = (z->left == NIL || z->right == NIL) ? z : treeSuccessor(z);
    Node *x = (y->left != NIL) ? y->left : y->right;

    if (x != NIL) x->parent = y->parent;

    if (y->parent == NIL) {
        root = x;
    } else if (y == y->parent->left) {
        y->parent->left = x;
    } else {
        y->parent->right = x;
    }

    if (y != z) z->key = y->key;

    delete y;
}

void insert(int k) {
    Node *y = NIL;
    Node *x = root;
    Node *z = new Node{k, NIL, NIL, nullptr};

    while (x != NIL) {
        y = x;
        if (z->key < x->key) x = x->left;
        else x = x->right;
    }

    z->parent = y;
    if (y == NIL) root = z;
    else if (z->key < y->key) y->left = z;
    else y->right = z;
}

void inorder(Node *u) {
    if (u == NIL) return;
    inorder(u->left);
    printf(" %d", u->key);
    inorder(u->right);
}

void preorder(Node *u) {
    if (u == NIL) return;
    printf(" %d", u->key);
    preorder(u->left);
    preorder(u->right);
}

int main() {
    int n, x;
    string com;

    // --- 番兵ノードを初期化 ---
    NIL = new Node{0, nullptr, nullptr, nullptr};
    NIL->left = NIL->right = NIL->parent = NIL;
    root = NIL;

    scanf("%d", &n);

    for (int i = 0; i < n; i++) {
        cin >> com;
        if (com[0] == 'f') {
            scanf("%d", &x);
            Node *t = find(root, x);
            printf(t != NIL ? "yes\n" : "no\n");
        } else if (com == "insert") {
            scanf("%d", &x);
            insert(x);
        } else if (com == "print") {
            inorder(root);
            printf("\n");
            preorder(root);
            printf("\n");
        } else if (com == "delete") {
            scanf("%d", &x);
            Node *t = find(root, x);
            if (t != NIL) treeDelete(t);
        }
    }

    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 22220
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> preorder;
vector<int> inorder;
vector<int> postorder;

class Node {
public:
	int value;
	Node* left;
	Node* right;

	Node(int value) {
		this->value = value;
		this->left = NULL;
		this->right = NULL;
	}
};

class BST {
public:
	Node* root;
	BST() {
		this->root = NULL;
	}

	void Insert(int num);
	bool Find(int num);
	Node* Search(int num);
	void Delete(int num);

private:
	Node* deleteNode(Node* node, int num); // 内部辅助函数
};

void BST::Insert(int num) {
	if (root == NULL) {
		root = new Node(num);
		return;
	}

	Node* curr = root;
	while (curr != NULL) {
		if (num < curr->value) {
			if (curr->left == NULL) {
				curr->left = new Node(num);
				return;
			}
			curr = curr->left; // 继续和左子树进行比较
		}
		else {
			if (curr->right == NULL) {
				curr->right = new Node(num);
				return;
			}
			curr = curr->right; // 继续和右子树进行比较
		}
	}
}

bool BST::Find(int num) {
	Node* curr = root;
	while (curr != NULL) {
		if (num < curr->value) {
			curr = curr->left;
		}
		else if (num > curr->value) {
			curr = curr->right;
		}
		else {
			return true;
		}
	}
	return false;
}

Node* BST::Search(int num) {
	Node* curr = root;
	while (curr != NULL) {
		if (num < curr->value) {
			curr = curr->left;
		}
		else if (num > curr->value) {
			curr = curr->right;
		}
		else {
			return curr;
		}
	}
	return NULL;
}

Node* BST::deleteNode(Node* root, int num) {
	if (root == NULL) 
		return NULL;

	if (num < root->value) { // 在左子树中找
		root->left = deleteNode(root->left, num);
	}
	else if (num > root->value) { // 在右子树中找
		root->right = deleteNode(root->right, num);
	}
	else { // 此时的root就是要删除的节点

		// ① 没有左子树
		if (root->left == NULL) {
			Node* rightChild = root->right;
			delete root;
			return rightChild;
		}

		// ② 没有右子树
		else if (root->right == NULL) {
			Node* leftChild = root->left;
			delete root;
			return leftChild;
		}

		// ③ 左右子树都有
		else {
			// 找右子树中的最小节点（即中序后继）
			Node* successor = root->right;
			while (successor->left != NULL) {
				successor = successor->left;
			}
			// 用后继的值替换当前节点
			root->value = successor->value;
			// 删除右子树中的那个后继节点
			root->right = deleteNode(root->right, successor->value);
		}
	}
	return root;
}


void BST::Delete(int num) {
	root = deleteNode(root, num);
}

// 前序遍历
void PreorderTraversal(Node* node) {
	if (node == NULL) {
		return;
	}
	preorder.push_back(node->value);
	PreorderTraversal(node->left);
	PreorderTraversal(node->right);
}

// 中序遍历
void InorderTraversal(Node* node) {
	if (node == NULL) {
		return;
	}
	InorderTraversal(node->left);
	inorder.push_back(node->value);
	InorderTraversal(node->right);
}

// 后序遍历
void PostorderTraversal(Node* node) {
	if (node == NULL) {
		return;
	}
	PostorderTraversal(node->left);
	PostorderTraversal(node->right);
	postorder.push_back(node->value);
}

void Print(Node *node) {
	inorder.clear();
	preorder.clear();
	postorder.clear();

	InorderTraversal(node);
	for (int i = 0; i < inorder.size(); i++) {
		
			cout << " ";
		cout << inorder[i];
	}
	cout << endl;

	PreorderTraversal(node);
	for (int i = 0; i < preorder.size(); i++) {
		
			cout << " ";
		cout << preorder[i];
	}
	cout << endl;

	//PostorderTraversal(node);
	//for (int i = 0; i < postorder.size(); i++) {
	//	if (i)
	//		cout << " ";
	//	cout << postorder[i];
	//}
	//cout << endl;
}

int main() {
	int n;
	cin >> n;
	BST* tree = new BST();

	for (int i = 0; i < n; i++) {
		string inst;
		cin >> inst;
		if(inst == "insert")
		{
			int num;
			cin >> num;
			tree->Insert(num);
		}
		else if (inst == "find")
		{
			int num;
			cin >> num;
			if (tree->Find(num))
				cout << "yes" << endl;
			else
				cout << "no" << endl;
		}
		else if (inst == "delete") {
			int num;
			cin >> num;
			tree->Delete(num);
		}
		else if (inst == "print")
		{
			Print(tree->root);
		}
	}
	
	return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 20156
final_rank: 7

code_snippet: #include<iostream>
using namespace std;

struct Node {
    int key;
    Node *parent, *left, *right;
    Node(int k) : key(k), parent(nullptr), left(nullptr), right(nullptr) {}
};

Node *root;

void insert (int k) {
    Node *x = root;
    Node *y = nullptr;
    Node *z;
    z = new Node(k);

    while ( x != nullptr ) {
        y = x;
        if ( z->key < x->key ) x = x->left;
        else x = x->right;
    }
    z->parent = y;
    if ( y == nullptr ) root = z;
    else if ( z->key < y->key ) y->left = z;
    else y->right = z;
}

Node * find(int k) {
    Node *x = root;
    while ( x != nullptr && k != x->key ) {
        if (k < x->key) x = x->left;
        else x = x->right;
    }
    return x;
}

Node * getMinimum(Node *u) {
    Node *v = nullptr;
    while( u != nullptr ) {
        v = u;
        u = u->left;
    }
    return v;
}

Node * getSuccessor(Node *u) {
    return getMinimum(u->right);
}

void treeDelete( int k ) {
    Node *z = find(k);
    Node *y, *x = nullptr;
    if ( z->left == nullptr || z->right == nullptr ) y = z;
    else y = getSuccessor(z);

    if ( y->left != nullptr ) x = y->left;
    else if (y->right != nullptr ) x = y->right;

    if ( x!= nullptr ) x->parent = y->parent;
    if ( y->parent != nullptr ) {
        if ( y == y->parent->left ) y->parent->left = x;
        else if ( y == y->parent->right ) y->parent->right = x;
        z->key = y->key;
    }
}

void inorder(Node *u) {
    if (u == nullptr) return;
    inorder(u->left);
    cout << " " << u->key;
    inorder(u->right);
}

void preorder(Node *u) {
    if (u == nullptr) return;
    cout << " " << u->key;
    preorder(u->left);
    preorder(u->right);
}

int main() {
    int m, x;
    cin >> m;
    string com;
    for (int i = 0; i < m; i++) {
        cin >> com;
        if ( com == "insert" ) {
            cin >> x;
            insert(x);
        }
        else if ( com == "print" ) {
            inorder(root);
            cout << endl;
            preorder(root);
            cout << endl;
        }
        else if ( com == "find" ) {
            cin >> x;
            if ( find(x) != nullptr ) cout << "yes" << endl;
            else cout << "no" << endl;
        }
        else if ( com == "delete" ) {
            cin >> x;
            treeDelete(x);
        }
    }
}
accuracy: 1
time_ms: 420
memory_kb: 22092
final_rank: 14

code_snippet: #include <cstdio>
#include <cstring>
#include <cstdlib>
#define max 50000
typedef struct Node{
    int m;
    Node *p,*l,*r;
}tree;
int n;
tree *root=NULL;
void preorder(tree *a){
    if(a==NULL) return;
    printf(" %d",a->m);
    preorder(a->l);
    preorder(a->r);
}
void inorder(tree *a){
    if(a==NULL) return;
    inorder(a->l);
    printf(" %d",a->m);
    inorder(a->r);
}
void insert(int k){
    tree *b=NULL;
    tree *c=root;
    tree *w;
    w=(tree*)malloc(sizeof(tree));//分配了内存，结束后还存在
    w->m=k;
    w->l=NULL;
    w->r=NULL;
    while(c!=NULL){
        b=c;//设置父节点
        if(w->m<c->m){
            c=c->l;
        }else c=c->r;
    }
    w->p=b;
    if(b==NULL){
        root=w;
    }else if(b->m>w->m){
        b->l=w;
    }else if(b->m<w->m){
        b->r=w;
    }
}
tree* find(int a){
    tree*q=root;
    while(q!=NULL&&q->m!=a){
        if(q->m<a){
            q=q->r;
        }else q=q->l;
    }
    return q;
}
/*void deletenode(int a){//删除操作
    tree* t=find(a);
    if(t->l==NULL&&t->r==NULL){
        if(t->p->l=t){
            tree *x=t->p;
            x->l=NULL;
            free(find(a));
        }else if(t->p->r=t){
            tree *x=t->p;
            x->r=NULL;
            free(find(a));
        }
    }else if(t->l!=NULL&t->r==NULL){
        if(t->p->l=t){
            tree *x=t->p;
            tree *y=t->l;
            x->l=y;
            y->p=x;
            free(find(a));
        }else if(t->p->r=t){
            tree *x=t->p;
            tree *y=t->l;
            x->r=y;
            y->p=x;
            free(find(a));
        }
    }else if(t->r!=NULL&t->l==NULL){
        if(t->p->l=t){
            tree *x=t->p;
            tree *y=t->r;
            x->l=y;
            y->p=x;
            free(find(a));
        }else if(t->p->r=t){
            tree *x=t->p;
            tree *y=t->r;
            x->r=y;
            y->p=x;
            free(find(a));
        }
    }else{

    }
}  有点复杂，学习下讲解的做法*/
tree* getMinimum(tree* a){//找到键值最小点
    while(a->l!=NULL){
        a=a->l;
    }
    return a;
}
tree* getSuccessor(tree* a){//寻找下一个结点,但我们是在有两个结点调用，所以只会走第一个框
    if(a->r!=NULL){
        tree *v=getMinimum(a->r);
        return v;
    }
    tree* v=a->p;
     while(v!=NULL&&a==v->r){
        a=v;
        v=v->p;
    }
    return v;
}
void deletenode(int a){
    tree* h=find(a);
    tree* y;
    if(h->l==NULL||h->r==NULL){//用y表示要删除的结点
        y=h;
    }else y=getSuccessor(h);
    //用x表示要删除的结点结点的子结点
    tree* x;
    if(y->l!=NULL){//三种情况都可
        x=y->l;
    }else x=y->r;
    //设置x的父结点
    if(x!=NULL){
    x->p=y->p;
    }
    if(y->p==NULL) {root=x;
    }else if(y->p->l==y){
        y->p->l=x;
    }else y->p->r=x;
    if(h!=y){
        h->m=y->m;
    }
    free(y);
    return;
}
int main(){
    scanf("%d",&n);
    char q[20];
    int e;
    for(int i=0;i<n;i++){
        scanf("%s",q);
        if(q[0]=='i'){
            scanf("%d",&e);
            insert(e);
        }else
        if(q[0]=='p'){
            inorder(root);
            printf("\n");
            preorder(root);
            printf("\n");
        }else
        if(q[0]=='f'){
            scanf("%d",&e);
            if(find(e)!=NULL){
                printf("yes\n");
            }else printf("no\n");
        }else
        if(q[0]=='d'){
            scanf("%d",&e);
            deletenode(e);
        }
    }
    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 21696
final_rank: 3

code_snippet: #include <iostream>
#include <string.h>
#include<vector>
using namespace std;

struct Node {
    int data;  // ノードが保持するデータ
    Node *right, *left, *parent; 

};

Node *root=NULL, *NIL=NULL;

void insert(int k) {
    Node *y = NIL; // 親
    Node *x = root; // 子
    Node *z;
    z = (Node *)malloc(sizeof(Node));
    z->data = k;
    z->left = NIL;
    z->right = NIL;

    while (x != NIL) { // 葉のとこまでいくようにする
        y = x;
        if (z->data < x->data) {
            x = x->left;
        } else {
            x = x->right;
        }
    }
    z->parent = y;
    if (y == NIL) {
        root = z;
    } else if (z->data < y->data) {
        y->left = z;
    } else {
        y->right = z;
    }
}

int countNodes(Node *p) {
    if (p == NULL) {
        return 0;
    } else {
        return 1 + countNodes(p->left) + countNodes(p->right);
    }
}
void inorder(Node *p, vector<int>& result) {
    if(p != NULL) {
        inorder(p->left, result); // 左ノードへ移動
        result.push_back(p->data);
        inorder(p->right, result); // 右ノードへ移動
    }
}

void preorder(Node *p, vector<int>& result) {
    if(p != NULL) {
        result.push_back(p->data);
        preorder(p->left, result); // 左ノードへ移動
        preorder(p->right, result); // 右ノードへ移動
    }
}

void printVector(const vector<int>& arr) {
    for (size_t i = 0; i < arr.size(); i ++) {
        cout << " ";
        cout << arr[i];
        if (i < arr.size() - 1) {

        }
    }
    cout << endl;
}   

bool find(Node* root, int k) {
    while (root != NULL) {
        if (k == root->data) {
            return true;
        } else if (k < root->data) {
            root = root->left;
        } else {
            root = root->right;
        }
    }
    return false;
}

void deleteNode(int k) {
    Node *z = root; // 削除するNode
    Node *p = NIL; // zの親

    while (z != NIL && z->data != k) {
        p = z;
        if (k < z->data) {
            z = z->left;
        } else {
            z = z->right;
        }
    }
    if (z == NIL) {
        return;
    }

    Node *target_node;
    Node *target_parent;

    if (z->left != NIL && z->right != NIL) {
        Node *y = z->right;
        Node *y_parent = z; 
        while (y->left != NIL) {
            y_parent = y;
            y = y->left;
        }
        z->data = y->data;

        target_node = y;
        target_parent = y_parent;
    } else {
        target_node = z;
        target_parent = p;
    }

    if (target_node->left == NIL && target_node->right ==NIL) { // zが子を持たない場合
        if (target_parent == NIL) {
            root = NIL;
        } else if (target_node == target_parent->left) {
            target_parent->left = NIL;
        } else if (target_node == target_parent->right) {
            target_parent->right = NIL;
        }
        free(target_node);
    } else if (target_node->left == NIL || target_node->right == NIL) { // zがちょうど１つの子を持つ場合
        Node *child_of_target = NIL; // z の唯一の子
        if (target_node->left != NIL) {
            child_of_target = target_node->left;
        } else {
            child_of_target = target_node->right;
        }

        if (target_parent == NIL) { // zがルートノードの時
            root = child_of_target;
            child_of_target->parent = NIL;
        } else if (target_node == target_parent->left) {
            target_parent->left = child_of_target;
            child_of_target->parent = target_parent;
        } else {
            target_parent->right = child_of_target;
            child_of_target->parent = target_parent;
        }
        free(target_node);
    } 
}





int main(int argc, char const *argv[])
{
    int n, k;
    string s;
    bool is_find;
    cin >> n;
    for (int i = 0; i < n; i ++) {
        cin >> s;
        if (s == "insert") {
            cin >> k;
            insert(k);
        } else if (s == "find") {
            cin >> k;
            is_find = find(root, k);
            if (is_find == true) {
                cout << "yes" << endl;
            } else {
                cout << "no" << endl;
            }
        } else if (s == "delete") {
            cin >> k;
            deleteNode(k);
        } else if (s == "print") {
            vector<int> inorder_result;
            vector<int> preorder_result;
            inorder(root, inorder_result);
            preorder(root, preorder_result);
            printVector(inorder_result);
            printVector(preorder_result);
        }
    }
    return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 26588
final_rank: 20

code_snippet: #include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;

struct Node {
    int key;
    Node *parent, *left, *right;
};

Node *NIL, *root;

void insert(int k) {
    Node *y = NIL;
    Node *x = root;
    Node *z = new Node;

    z->key = k;
    z->left = NIL;
    z->right = NIL;

    while (x != NIL) {
        y = x;
        if (z->key < y->key) {
            x = y->left;
        } else {
            x = y->right;
        }
    }

    z->parent = y;

    if (y==NIL) {
        root = z;
    } else if (z->key < y->key) {
        y->left = z;
    } else {
        y-> right = z;
    }
}

Node* find(Node* x, int k) {
    while (x != NIL && k != x->key) {
        if (k < x->key) {
            x = x->left;
        } else {
            x = x->right;
        }
    }
    return x;
}

Node* treeMinimum(Node *x) {
    while (x->left != NIL) {
        x = x->left;
    }
    return x;
}

// Inorderで次に得られるノードを見る
Node* treeSuccessor(Node *x) {
    if (x->right != NIL) return treeMinimum(x->right);
    Node *y = x->parent;
    while (y != NIL && x == y->right) {
        x = y;
        y = y->parent;
    }
    return y;
}

void treeDelete(Node *z) {
    Node *y;
    Node *x;

    // 削除するノードを決める
    if (z->left == NIL || z->right == NIL) y = z;
    else y = treeSuccessor(z);

    // yの子xを決める
    if (y->left != NIL) {
        x = y->left;
    } else {
        x = y->right;
    }

    if (x != NIL) {
        x->parent = y->parent;
    }

    // yの親から見たxはどういう値か
    if (y->parent == NIL) {
        root = x;
    } else {
        if (y == y->parent->left) {
            y->parent->left = x;
        } else {
            y->parent->right = x;
        }
    }

    // case3の場合の処理
    if (y != z) {
        z->key = y->key;
    }

    free(y); // メモリの解放
}

void inorder(Node *u) {
    if (u==NIL) return;
    inorder(u->left);
    printf(" %d", u->key);
    inorder(u->right);
}

void preorder(Node *u) {
    if (u==NIL) return ;
    printf(" %d", u->key);
    preorder(u->left);
    preorder(u->right);
}

int main()
{
    int n,i,x;
    string com;

    scanf("%d", &n);

    for (i=0; i<n; i++) {
        cin >> com;
        if (com[0] == 'f') {
            scanf("%d", &x);
            Node *t = find(root,x);
            if (t != NIL) printf("yes\n");
            else printf("no\n");
        } else if (com == "insert") {
            scanf("%d", &x);
            insert(x);
        } else if (com == "print") {
            inorder(root);
            printf("\n");
            preorder(root);
            printf("\n");
        } else if (com == "delete") {
            scanf("%d", &x);
            treeDelete(find(root,x));
        }
    }

    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 22200
final_rank: 9

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define loop(a,b) for (int a = 0;a < b;a++)
#define rep(a,b,c) for(int a = b;a < c;a++)
#define vec(a) vector<a>

struct Node{
    int key;
    Node *left,*right,*parent;
    Node(int key):key(key),left(nullptr),right(nullptr),parent(nullptr){};
};

class BinarySearchTree{
    private:
        Node* root;
        Node* insert(Node* node,int key){
            Node* z = new Node(key);
            Node* y = nullptr;
            Node* x = root;
            while(x != nullptr){
                y = x;
                if(z->key < x->key) x = x->left;
                else x = x->right;
            }
            z->parent = y;
            if(y == nullptr) root = z;
            else if(z->key < y->key) y->left = z;
            else y->right = z;
            return z;
        }
        void inorder(Node* node){
            if(node == nullptr) return;
            inorder(node->left);
            cout <<" "<< node->key;
            inorder(node->right);
        }
        void preorder(Node* node){
            if(node == nullptr) return;
            cout << " "<< node->key;
            preorder(node->left);
            preorder(node->right);
        }
        
        Node* find(Node* node,int key){
            while(node != nullptr && node->key != key){
                if(key < node->key) node = node->left;
                else node = node->right;
            }
            return node;
        }
        Node* find_min(Node* node) {
            while (node->left != nullptr) {
                node = node->left;
            }
            return node;
        }
        
        void remove(Node* node,int key){
            Node* z = find(node,key);
            if(z == nullptr) return;
            
            
            if(z->left == nullptr && z->right == nullptr) {
                if(z->parent == nullptr) {
                    root = nullptr;  
                } else if(z->parent->left == z) {
                    z->parent->left = nullptr;
                } else {
                    z->parent->right = nullptr;
                }
                delete z;
            }
            else if(z->left == nullptr || z->right == nullptr) {
                Node* child = (z->left != nullptr) ? z->left : z->right;
                
                if(z->parent == nullptr) {
                    root = child;  
                } else if(z->parent->left == z) {
                    z->parent->left = child;
                } else {
                    z->parent->right = child;
                }
                
                if(child != nullptr) {
                    child->parent = z->parent;
                }
                delete z;
            }
           
            else {
                
                Node* successor = find_min(z->right);
                
                
                z->key = successor->key;
                
                
                if(successor->parent->left == successor) {
                    successor->parent->left = successor->right;
                } else {
                    successor->parent->right = successor->right;
                }
                
                if(successor->right != nullptr) {
                    successor->right->parent = successor->parent;
                }
                delete successor;
            }
        }

    public:
        BinarySearchTree():root(nullptr){};
        void print(){
            inorder(root);
            cout << endl;
            preorder(root);
            cout << endl;
        }
        void insert(int key){
            insert(root,key);
        }
        bool find(int key){
            Node* node = find(root,key);
            if(node != nullptr) return 1;
            else return 0;
        }
        void remove(int key){
            remove(root,key);
        }
};
int main()
{
    int n;
    cin >> n;
    BinarySearchTree bst;
    loop(i,n){
        string command;
        int key;
        cin >> command;
        if(command == "insert"){
            cin >> key;
            bst.insert(key);
        } 
        else if(command == "find") {
            cin >> key;
            cout << (bst.find(key) ? "yes" : "no") << endl;
        }
        else if(command == "print") {
            bst.print();
        }
        else if(command == "delete"){
            cin >> key;
            bst.remove(key);
        }   
    }
}
accuracy: 1
time_ms: 420
memory_kb: 22028
final_rank: 13

code_snippet: #include <iostream>
#include <string>
using namespace std;
class node{
    public:
        node* right;
        node* left;
        node* parent;
        int key;
};
class tree{
    private:
        node* root;
    public:
        tree(){root = 0;}
        void insert(int k);
        node* find(int k);
        void deleteb(int k);
        void inorder(node* u);
        void preorder(node* u);
        void print();
};
void tree::insert(int k){
    node* z = new node();
    z->right = 0;
    z->left = 0;
    z->parent = 0;
    z->key = k;
    node* y = 0; // xの親
    node* x = root; // 根
    while(x!=0){
        y = x; // 親を設定
        if(z->key < x->key){
            x = x->left; // 左の子へ移動
        }
        else{
            x = x->right; // 右の子へ移動
        }
    }
    z->parent = y;
    if(y==0){ // 木が空の場合
        root = z;
    }
    else if(z->key < y->key){
        y->left = z; // 左の子にする
    }
    else{
        y->right = z; // 右の子にする
    }
}
node* tree::find(int k){
    node* x = root; // 根
    while(x!=0){
        if(k == x->key){
            return x; // 見つかった
        }
        else if(k < x->key){
            x = x->left; // 左の子へ移動
        }
        else{
            x = x->right; // 右の子へ移動
        }
    }
    return 0; // 見つからなかった
}
void tree::deleteb(int k){
    node* y = 0; // xの親
    node* x = root; // 根
    while(k != x->key){
        y = x; // 親を設定
        if(k < x->key){
            x = x->left; // 左の子へ移動
        }
        else{
            x = x->right; // 右の子へ移動
        }
    }
    if(x->left == 0 && x->right == 0){ // 0個の子
        if(y==0){
            root = 0;
        }
        else if(y->left == x){
            y->left = 0;
        }
        else{
            y->right = 0;
        }
    }
    else if(x->left == 0){ // 1個の子（右の子）
        if(y==0){
            root = x->right;
            x->right->parent = 0;
        }
        else if(y->left == x){
            y->left = x->right;
            x->right->parent = y;
        }
        else{
            y->right = x->right;
            x->right->parent = y;
        }
    }
    else if(x->right == 0){ // 1個の子（左の子）
        if(y==0){
            root = x->left;
            x->left->parent = 0;
        }
        else if(y->left == x){
            y->left = x->left;
            x->left->parent = y;
        }
        else{
            y->right = x->left;
            x->left->parent = y;
        }
    }
    else{ // 2個の子
        node* yt = x; // xtの親
        node* xt = x->right;
        while(xt->left != 0){ // 探索（つぎに大きい要素）
            yt = xt;
            xt = xt->left;
        }
        x->key = xt->key; // 頂点xに割り当て
        if(yt==x){ // xtの親がxのまま
            if(xt->right == 0){
                x->right = 0;
            }
            else{
                x->right = xt->right;
                xt->right->parent = x;
            }
        }
        else{
            if(xt->right == 0){
                yt->left = 0;
            }
            else{
                yt->left = xt->right;
                xt->right->parent = yt;
            }
        }
        x = xt;
    }
    delete x; // メモリの解放
}
// 中間順
void tree::inorder(node* u){
    if(u==0){
        return;
    }
    inorder(u->left);
    cout << ' ' << u->key;
    inorder(u->right);
}
// 先行順
void tree::preorder(node* u){
    if(u==0){
        return;
    }
    cout << ' ' << u->key;
    preorder(u->left);
    preorder(u->right);
}
void tree::print(){
    inorder(root);
    cout << endl;
    preorder(root);
    cout << endl;
}
int main(){
    int m;
    cin >> m;
    tree T;
    for(int i=0; i<m; i++){
        string com;
        cin >> com;
        if(com=="insert"){
            int k;
            cin >> k;
            T.insert(k);
        }
        else if(com=="find"){
            int k;
            cin >> k;
            if(T.find(k)!=0){
                cout << "yes" << endl;
            }
            else{
                cout << "no" << endl;
            }
        }
        else if(com=="delete"){
            int k;
            cin >> k;
            T.deleteb(k);
        }
        else if(com=="print"){
            T.print();
        }
    }
    return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 22196
final_rank: 16

code_snippet: // 2025/07/17 Tazoe

#include <iostream>
#include <string>
using namespace std;

class node{
public:
	node* right;
	node* left;
	node* parent;
	int key;
};

class tree{
private:
	node* root;
public:
	tree(){root = 0;}
	void insert(int k);
	node* find(int k);
	void deleteb(int k);
	void inorder(node* u);
	void preorder(node* u);
	void print();
};

void tree::insert(int k)
{
	node* z = new node();
	z->right = 0;
	z->left = 0;
	z->parent = 0;
	z->key = k;
	
	node* y = 0;		// xの親
	node* x = root;		// 根
	
	while(x!=0){
		y = x;				// 親を設定
		if(z->key < x->key){
			x = x->left;		// 左の子へ移動
		}
		else{
			x = x->right;		// 右の子へ移動
		}
	}
	
	z->parent = y;
	
	if(y==0){			// 木が空の場合
		root = z;
	}
	else if(z->key < y->key){
		y->left = z;			// 左の子にする
	}
	else{
		y->right = z;			// 右の子にする
	}
}

node* tree::find(int k)
{
	node* x = root;		// 根
	
	while(x!=0){
		if(k == x->key){
			return x;			// 見つかった
		}
		else if(k < x->key){
			x = x->left;		// 左の子へ移動
		}
		else{
			x = x->right;		// 右の子へ移動
		}
	}
	
	return 0;			// 見つからなかった
}

void tree::deleteb(int k)
{
	node* y = 0;		// xの親
	node* x = root;		// 根
	
	while(k != x->key){
		y = x;				// 親を設定
		if(k < x->key){
			x = x->left;		// 左の子へ移動
		}
		else{
			x = x->right;		// 右の子へ移動
		}
	}
	
	if(x->left == 0 && x->right == 0){	// 0個の子
		if(y==0){
			root = 0;
		}
		else if(y->left == x){
			y->left = 0;
		}
		else{
			y->right = 0;
		}
	}
	else if(x->left == 0){				// 1個の子（右の子）
		if(y==0){
			root = x->right;
			x->right->parent = 0;
		}
		else if(y->left == x){
			y->left = x->right;
			x->right->parent = y;
		}
		else{
			y->right = x->right;
			x->right->parent = y;
		}
	}
	else if(x->right == 0){				// 1個の子（左の子）
		if(y==0){
			root = x->left;
			x->left->parent = 0;
		}
		else if(y->left == x){
			y->left = x->left;
			x->left->parent = y;
		}
		else{
			y->right = x->left;
			x->left->parent = y;
		}
	}
	else{								// 2個の子
		node* yt = x;					// xtの親
		node* xt = x->right;
		while(xt->left != 0){			// 探索（つぎに大きい要素）
			yt = xt;
			xt = xt->left;
		}
		x->key = xt->key;				// 頂点xに割り当て
		if(yt==x){						// xtの親がxのまま
			if(xt->right == 0){
				x->right = 0;
			}
			else{
				x->right = xt->right;
				xt->right->parent = x;
			}
		}
		else{
			if(xt->right == 0){
				yt->left = 0;
			}
			else{
				yt->left = xt->right;
				xt->right->parent = yt;
			}
		}
		
		x = xt;
	}
	
	delete x;			// メモリの解放
}

// 中間順
void tree::inorder(node* u)
{
	if(u==0){
		return;
	}
	
	inorder(u->left);
	cout << ' ' << u->key;
	inorder(u->right);
}

// 先行順
void tree::preorder(node* u)
{
	if(u==0){
		return;
	}
	
	cout << ' ' << u->key;
	preorder(u->left);
	preorder(u->right);
}

void tree::print()
{
	inorder(root);
	cout << endl;
	preorder(root);
	cout << endl;
}


int main()
{
	int m;
	cin >> m;
	
	tree T;
	
	for(int i=0; i<m; i++){
		string com;
		cin >> com;
		
		if(com=="insert"){
			int k;
			cin >> k;
			
			T.insert(k);
		}
		else if(com=="find"){
			int k;
			cin >> k;
			
			if(T.find(k)!=0){
				cout << "yes" << endl;
			}
			else{
				cout << "no" << endl;
			}
		}
		else if(com=="delete"){
			int k;
			cin >> k;
			
			T.deleteb(k);
		}
		else if(com=="print"){
			T.print();
		}
	}
	
	return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 22192
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef pair<int,int> PII;
struct node{
    int p,l,r,key;
};
const int N=5e5+5;
node tree[N];
int idx=0,root=-1;
void insert(int z){
    int y=-1,x=root;
    while(x!=-1){
        y=x;
        if(tree[z].key<tree[x].key) x=tree[x].l;
        else x=tree[x].r;
    }
    tree[z].p=y;
    if(y==-1){
        root=z;
    }else if(tree[z].key<tree[y].key){
        tree[y].l=z;
    }else{
        tree[y].r=z;
    }
}
void dfs1(int u){
    if(u==-1) return;
    dfs1(tree[u].l);
    cout<<" "<<tree[u].key;
    dfs1(tree[u].r);
}
void dfs2(int u){
    if(u==-1) return;
    cout<<" "<<tree[u].key;
    dfs2(tree[u].l);
    dfs2(tree[u].r);
}
bool find(int k,int u){
    if(u==-1) return false;
    if(k==tree[u].key) return true;
    else if(k<tree[u].key) return find(k,tree[u].l);
    else return find(k,tree[u].r);
}
void Delete(int k,int u){
    if(u==-1) return;
    if(tree[u].key==k){
        int pre=tree[u].p;
        int ls=tree[u].l,rs=tree[u].r;
        if(pre==-1){
            if(ls==-1&&rs==-1){
                root=-1;
            }else if(ls!=-1&&rs!=-1){
                int v=rs;
                while(tree[v].l!=-1) v=tree[v].l;
                tree[u].key=tree[v].key;
                int p1=tree[v].p;
                if(tree[p1].l==v) tree[p1].l=-1;
                else tree[p1].r=-1;
            }else if(ls!=-1){
                root=ls;
            }else{
                root=rs;
            }
        }else{
            if(ls==-1&&rs==-1){
                if(tree[pre].l==u) tree[pre].l=-1;
                else tree[pre].r=-1;
            }else if(ls!=-1&&rs!=-1){
                int v=rs;
                while(tree[v].l!=-1) v=tree[v].l;
                tree[u].key=tree[v].key;
                int p1=tree[v].p;
                if(tree[p1].l==v) tree[p1].l=-1;
                else tree[p1].r=-1;
            }else if(ls!=-1){
                tree[ls].p=tree[u].p;
                if(tree[pre].l==u) tree[pre].l=ls;
                else tree[pre].r=ls;
            }else{
                tree[rs].p=tree[u].p;
                if(tree[pre].l==u) tree[pre].l=rs;
                else tree[pre].r=rs;
            }
        }
    }
    else if(k<tree[u].key) Delete(k,tree[u].l);
    else Delete(k,tree[u].r);
}
void solve(){
    int n;cin>>n;
    for(int i=0;i<n;i++){
        string s;cin>>s;
        if(s=="insert"){
            int k;cin>>k;
            int z=idx++;
            tree[z].key=k;
            tree[z].l=tree[z].r=-1;
            insert(z);
        }else if(s=="print"){
            dfs1(root);
            cout<<endl;
            dfs2(root);
            cout<<endl;
        }else if(s=="find"){
            int k;cin>>k;
            if(find(k,root)) cout<<"yes"<<endl;
            else cout<<"no"<<endl;
        }else if(s=="delete"){
            int k;cin>>k;
            Delete(k,root);
        }
    }
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int T=1;
    // cin>>T;
    for(int t=1;t<=T;t++){
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 17472
final_rank: 1

code_snippet: #include<iostream>
using namespace std;

struct Node {
    int key;
    Node *right, *left, *parent;
};

Node *root, *NIL;

Node * treeMinimum(Node *x) {
    while(x->left != NIL) {
        x = x->left;
    }
    return x;
}

Node * find(Node *u, int k) {
    while(u !=NIL && k != u->key) {
        if(k < u->key) {
            u = u->left;
        } else {
            u = u->right;
        }
    }
    return u;
}

Node * treeSuccessor(Node *x) {
    if(x->right != NIL) {
        return treeMinimum(x->right);
    }
    Node *y = x->parent;
    while(y != NIL && x == y->right) {
        x = y;
        y = y->parent;
    }
    return y;
}

void treeDelete(Node *z) {
    Node *x, *y;
    if(z->left == NIL || z->right == NIL) {
        y = z;
    } else {
        y = treeSuccessor(z);
    }
    if(y->left != NIL) {
        x = y->left;
    } else {
        x = y->right;
    }
    if(x != NIL) {
        x->parent = y->parent;
    }
    if(y->parent == NIL) {
        root = x;
    } else {
        if(y == y->parent->left) {
            y->parent->left = x;
        } else {
            y->parent->right = x;
        }
    }

    if(y != z) {
        z->key = y->key;
    }
    free(y);
}

void insert(int k) {
    Node *y = NIL;
    Node *x = root;
    Node *z;
    z = (Node *)malloc(sizeof(Node));
    z->key = k;
    z->left = NIL;
    z->right = NIL;
    while(x != NIL){
        y = x;
        if(z->key < x->key){
            x = x->left;
        }else{
            x = x->right;
        }
    }
    z->parent = y;
    if(y == NIL){
        root = z;
    }else{
        if(z->key < y->key){
            y->left = z;
        }else{
            y->right = z;
        }
    }
}

void inorder(Node *u) {
    if(u == NIL) {
        return;
    }
    inorder(u->left);
    cout << " " << u->key;
    inorder(u->right);
}

void preorder(Node *u) {
    if (u == NIL) {
        return;
    }
    cout << " " << u->key;
    preorder(u->left);
    preorder(u->right);
}

int main() {
    int m;
    string command;
    int key;
    cin >> m;
    for(int i=0; i<m; i++){
        cin >> command;
        if(command == "insert"){
            cin >> key;
            insert(key);
        }else if(command == "find"){
            cin >> key;
            if(find(root, key) != NIL){
                cout << "yes\n";
            }else{
                cout << "no\n";
            }
        }else if(command == "delete"){
            cin >> key;
            treeDelete(find(root, key));
        }else if(command == "print"){
            inorder(root);
            cout << "\n";
            preorder(root);
            cout << "\n";
        }
    }
    return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 22104
final_rank: 12

code_snippet: #include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct Node {
    int key;
    Node *left, *right, *parent;
};

Node *root, *NIL;

Node *treeMinimum(Node *x) {
    while (x->left != NIL) x = x->left;
    return x;
}

Node *find(Node *u, int k) {
    while (u != NIL && k != u->key) {
        if (k < u->key) u = u->left;
        else u = u->right;
    }
    return u;
}

Node *treeSuccessor(Node *x) {
    if (x->right != NIL) return treeMinimum(x->right);
    Node *y = x->parent;
    while (y != NIL && x == y->right) {
        x = y;
        y = y->parent;
    }
    return y;
}

void treeDelete(Node *z) {
    Node *y, *x;

    if (z->left == NIL || z->right == NIL) {
        y = z;
    } else {
        y = treeSuccessor(z);
    }

    if (y->left != NIL) x = y->left;
    else x = y->right;

    if (x != NIL) x->parent = y->parent;

    if (y->parent == NIL) {
        root = x;
    } else if (y == y->parent->left) {
        y->parent->left = x;
    } else {
        y->parent->right = x;
    }

    if (y != z) {
        z->key = y->key;
    }

    free(y);
}

void insert(int k) {
    Node *z = (Node *)malloc(sizeof(Node));
    z->key = k;
    z->left = z->right = z->parent = NIL;

    Node *y = NIL;
    Node *x = root;

    while (x != NIL) {
        y = x;
        if (z->key < x->key) x = x->left;
        else x = x->right;
    }

    z->parent = y;
    if (y == NIL) root = z;
    else if (z->key < y->key) y->left = z;
    else y->right = z;
}

void inorder(Node *u) {
    if (u == NIL) return;
    inorder(u->left);
    cout << " " << u->key;
    inorder(u->right);
}

void preorder(Node *u) {
    if (u == NIL) return;
    cout << " " << u->key;
    preorder(u->left);
    preorder(u->right);
}

void print() {
    inorder(root);
    cout << endl;
    preorder(root);
    cout << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    NIL = (Node *)malloc(sizeof(Node));
    NIL->left = NIL->right = NIL->parent = NIL;
    root = NIL;

    string line;
    while (getline(cin, line)) {
        if (line.empty()) continue;

        stringstream ss(line);
        string cmd;
        int k;
        ss >> cmd;

        if (cmd == "insert") {
            ss >> k;
            insert(k);
        } else if (cmd == "find") {
            ss >> k;
            Node *res = find(root, k);
            cout << (res != NIL ? "yes" : "no") << endl;
        } else if (cmd == "delete") {
            ss >> k;
            Node *z = find(root, k);
            if (z != NIL) treeDelete(z);
        } else if (cmd == "print") {
            print();
        }
    }

    return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 21908
final_rank: 18

code_snippet: #include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct Node {
    int key;
    Node *left, *right, *parent;
};

// グローバル変数
Node *root, *NIL;

// 最小ノード
Node *treeMinimum(Node *x) {
    while (x->left != NIL) x = x->left;
    return x;
}

// 探索
Node *find(Node *u, int k) {
    while (u != NIL && k != u->key) {
        if (k < u->key) u = u->left;
        else u = u->right;
    }
    return u;
}

// 次節点
Node *treeSuccessor(Node *x) {
    if (x->right != NIL) return treeMinimum(x->right);
    Node *y = x->parent;
    while (y != NIL && x == y->right) {
        x = y;
        y = y->parent;
    }
    return y;
}

// 削除
void treeDelete(Node *z) {
    Node *y, *x;

    if (z->left == NIL || z->right == NIL) {
        y = z;
    } else {
        y = treeSuccessor(z);
    }

    if (y->left != NIL) x = y->left;
    else x = y->right;

    if (x != NIL) x->parent = y->parent;

    if (y->parent == NIL) {
        root = x;
    } else if (y == y->parent->left) {
        y->parent->left = x;
    } else {
        y->parent->right = x;
    }

    if (y != z) {
        z->key = y->key;
    }

    free(y);
}

// 挿入
void insert(int k) {
    Node *z = (Node *)malloc(sizeof(Node));
    z->key = k;
    z->left = z->right = z->parent = NIL;

    Node *y = NIL;
    Node *x = root;

    while (x != NIL) {
        y = x;
        if (z->key < x->key) x = x->left;
        else x = x->right;
    }

    z->parent = y;
    if (y == NIL) root = z;
    else if (z->key < y->key) y->left = z;
    else y->right = z;
}

// inorder
void inorder(Node *u) {
    if (u == NIL) return;
    inorder(u->left);
    cout << " " << u->key;
    inorder(u->right);
}

// preorder
void preorder(Node *u) {
    if (u == NIL) return;
    cout << " " << u->key;
    preorder(u->left);
    preorder(u->right);
}

// 出力
void print() {
    inorder(root);
    cout << endl;
    preorder(root);
    cout << endl;
}

// メイン処理
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // NIL 初期化
    NIL = (Node *)malloc(sizeof(Node));
    NIL->left = NIL->right = NIL->parent = NIL;
    root = NIL;

    string line;
    while (getline(cin, line)) {
        if (line.empty()) continue;

        stringstream ss(line);
        string cmd;
        int k;
        ss >> cmd;

        if (cmd == "insert") {
            ss >> k;
            insert(k);
        } else if (cmd == "find") {
            ss >> k;
            Node *res = find(root, k);
            cout << (res != NIL ? "yes" : "no") << endl;
        } else if (cmd == "delete") {
            ss >> k;
            Node *z = find(root, k);
            if (z != NIL) treeDelete(z);
        } else if (cmd == "print") {
            print();
        }
    }

    return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 21900
final_rank: 17

code_snippet: #include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iostream>
using namespace std;

struct Node {
    int key;
    Node *right, *left, *parent;
};

Node *root, *NIL;

Node * treeMinimum(Node *x) {
    while( x->left != NIL ) x = x->left;
    return x;
}

Node * find(Node *u, int k) {
    while( u != NIL && k != u->key ) {
        if ( k < u-> key ) u = u->left;
        else u = u->right;
    }
    return u;
}

Node * treeSuccessor(Node *x) {
    if ( x->right != NIL ) return treeMinimum(x->right);
    Node *y = x->parent;
    while(y!= NIL && x == y->right) {
        x = y;
        y = y->parent;
    }
    return y;
}

void treeDelete(Node *z) {
    Node *y;
    Node *x;
    if (z->left == NIL || z->right == NIL) y=z;
    else y = treeSuccessor(z);
    if (y->left != NIL) {
        x = y->left;
    } else {
        x = y->right;
    }
    if (x != NIL) {
        x->parent = y->parent;
    }
    if (x != NIL) {
        x->parent = y->parent;
    }
    if (y->parent == NIL) {
        root = x;
    } else {
        if (y==y->parent->left) {
            y->parent->left = x;
        } else {
            y->parent->right = x;
        }
    }
    if (y!=z) {
        z->key = y->key;
    }
    free(y);
}

void insert(int k) {
    Node *y = NIL;
    Node *x = root;
    Node *z;

    z = (Node *)malloc(sizeof(Node));
    z->key = k;
    z->left = NIL;
    z->right = NIL;

    while ( x != NIL) {
        y = x;
        if ( z->key < x->key ) {
            x = x->left;
        } else {
            x = x->right;
        }
    }
    z->parent = y;
    if ( y==NIL) {
        root = z;
    } else {
        if (z->key < y->key) {
            y->left = z;
        } else {
            y->right = z;
        }
    }
}

void inorder(Node *u) {
    if ( u == NIL ) return;
    inorder(u->left);
    printf(" %d", u->key);
    inorder(u->right);
}
void preorder(Node *u) {
    if ( u == NIL ) return;
    printf(" %d", u->key);
    preorder(u->left);
    preorder(u->right);
}

int main() {
    int n, i, x;
    string com;

    scanf("%d", &n);

    for ( i = 0; i<n; i++ ) {
        cin >> com;
        if ( com[0] == 'f' ) {
            scanf("%d", &x);
            Node *t = find(root, x);
            if ( t != NIL ) printf("yes\n");
            else printf("no\n");
        } else if ( com == "insert" ) {
            scanf("%d", &x);
            insert(x);
        } else if ( com == "print" ) {
            inorder(root);
            printf("\n");
            preorder(root);
            printf("\n");
        } else if ( com == "delete" ) {
            scanf("%d", &x);
            treeDelete(find(root, x));
        }
    }
    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 21996
final_rank: 8

code_snippet: #include<stdio.h>
#include<stdlib.h>

struct node{
struct node *right;
struct node *left;
struct node *parent;
int key;
};
typedef struct node *Node;
#define NIL NULL

Node root;

Node treeMinimum(Node x){
while(x->left != NIL)x=x->left;
return x;
}

Node treeSearch(Node u, int k){
while(u!=NIL){
if(u->key==k)break;
if(k<u->key){
u=u->left;
}else{
u=u->right;
}
}
return u;
}

Node treeSuccessor(Node x){
if(x->right!=NIL){
return treeMinimum(x->right);
}
Node y=x->parent;
while(y!=NIL && x==y->right){
x=y;
y=y->parent;
}
return y;
}

void treeDelete(Node z){

Node y; // node to be deleted
Node x; // child of y
if(z==NIL)return;
if(z->left==NIL || z->right==NIL){
y=z;
}else{
y=treeSuccessor(z);
}
if(y->left!=NIL){
x=y->left;
}else{
x=y->right;
}
if(x!=NIL){
x->parent=y->parent;
}
if(y->parent==NIL){
root=x;
}else{
if(y==y->parent->left){
y->parent->left=x;
}else{
y->parent->right=x;
}
}
if(y!=z) z->key=y->key;
}

void insert(int k){
Node y = NIL;
Node x = root;
Node z;

z = (struct node*)malloc(sizeof(struct node));
z->key = k;
z->left = NIL;
z->right = NIL;
while(x!=NIL){
y=x;
if(z->key < x->key){
x=x->left;
}else{
x=x->right;
}
}
z->parent=y;
if(y==NIL){
root=z;
}else{
if(z->key < y->key){
y->left=z;
    }else{
	y->right=z;
}


}
}

void inorder(Node u){
if(u==NIL)return;
inorder(u->left);
printf(" %d",u->key);
inorder(u->right);
}
void preorder(Node u){
if(u==NIL)return;
printf(" %d",u->key);
preorder(u->left);
preorder(u->right);
}

int main(){
int n, i, x;
char com[20];
scanf("%d", &n);

for ( i = 0; i < n; i++ ){
scanf("%s", com);
if ( com[0] == 'f' ){
scanf("%d", &x);
Node t = treeSearch(root, x);
if ( t != NIL ) printf("yes\n");
else printf("no\n");
} else if ( com[0] == 'i' ){
scanf("%d", &x);
insert(x);
} else if ( com[0] == 'p' ){
inorder(root);
printf("\n");
preorder(root);
printf("\n");
} else if ( com[0] == 'd' ){
scanf("%d", &x);
treeDelete(treeSearch(root, x));
}
}

return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 21636
final_rank: 4

code_snippet: #include <stdio.h>
#include <iostream>

using namespace std;

#define BUF_SIZE 22

struct Node{
	Node(){
		left_child = right_child = parent = 0;
		data = 0;
	}
	Node *left_child,*right_child,*parent;
	long long data;
};

class Tree{
public:
	Tree(){
		root = new Node();
		num_of_node = 0;
	}
	void insert(long long insert_data){
		if(num_of_node == 0){
			root->data = insert_data;
			num_of_node++;
		}else{
			Node* tmp = root;
			while(true){
				if(tmp->data < insert_data){
					if(tmp->right_child == 0){
						tmp->right_child = new Node();
						tmp->right_child->data = insert_data;
						tmp->right_child->parent = tmp;
						num_of_node++;
						break;
					}else{
						tmp = tmp->right_child;
					}
				}else{
					if(tmp->left_child == 0){
						tmp->left_child = new Node();
						tmp->left_child->data = insert_data;
						tmp->left_child->parent = tmp;
						num_of_node++;
						break;
					}else{
						tmp = tmp->left_child;
					}
				}
			}
		}
	}

	bool find(long long data){
		if(num_of_node == 0){
			return false;
		}else{
			Node* tmp = root;
			while(true){
				if(tmp->data < data){
					if(tmp->right_child == 0){
						return false;
					}else{
						tmp = tmp->right_child;
					}
				}else if(tmp->data > data){
					if(tmp->left_child == 0){
						return false;
					}else{
						tmp = tmp->left_child;
					}
				}else{
					return true;
				}
			}
		}
	}

	void deleteNode(long long delete_data){
		if(num_of_node == 0){
			return;
		}else{
			doDELETE(root,delete_data);
		}
	}

	void print(){
		inORDER(root);
		printf("\n");
		preORDER(root);
		printf("\n");
	}

private:
	Node* root;
	int num_of_node;

private:

	Node* findNextNode(Node* node){
		Node* tmp = node;
		while(tmp->left_child != 0) tmp = tmp->left_child;
		return tmp;
	}

	void doDELETE(Node* node,long long delete_data){

		Node* tmp = node;
		while(true){
			if(tmp->data < delete_data){
				if(tmp->right_child == 0){
					//Do nothing
					break;
				}else{
					tmp = tmp->right_child;
				}
			}else if(tmp->data > delete_data){
				if(tmp->left_child == 0){
					//Do nothing
					break;
				}else{
					tmp = tmp->left_child;
				}
			}else{
				if(tmp->left_child == 0 && tmp->right_child == 0){
					if(tmp->parent->data < tmp->data){
						tmp->parent->right_child = 0;
					}else if(tmp->parent->data > tmp->data){
						tmp->parent->left_child = 0;
					}else{
						tmp->parent->right_child = 0;
					}
					delete tmp;
					num_of_node--;
					break;
				}else if(tmp->left_child == 0 && tmp->right_child != 0){

					if(tmp->parent->data < tmp->data){
						tmp->parent->right_child = tmp->right_child;
					}else if(tmp->parent->data > tmp->data){
						tmp->parent->left_child = tmp->right_child;
					}else{
						tmp->parent->right_child = 0;
					}
					tmp->right_child->parent = tmp->parent;
					delete tmp;
					num_of_node--;

					break;
				}else if(tmp->left_child != 0 && tmp->right_child == 0){

					if(tmp->parent->data < tmp->data){
						tmp->parent->right_child = tmp->left_child;
					}else if(tmp->parent->data > tmp->data){
						tmp->parent->left_child = tmp->left_child;
					}else{
						tmp->parent->right_child = 0;
					}
					tmp->left_child->parent = tmp->parent;
					delete tmp;
					num_of_node--;

					break;
				}else{
					Node* next_node = findNextNode(tmp->right_child);
					tmp->data = next_node->data;
					doDELETE(tmp->right_child,next_node->data);
					break;
				}
			}
		}
	}

	void preORDER(Node* node){
		printf(" %lld",node->data);
		if(node->left_child != 0) preORDER(node->left_child);
		if(node->right_child != 0) preORDER(node->right_child);
	}

	void inORDER(Node* node){
		if(node->left_child != 0) inORDER(node->left_child);
		printf(" %lld",node->data);
		if(node->right_child != 0) inORDER(node->right_child);
	}
};


int main(){
	int m;
	long long insert_data,search_data,delete_data;
	long long minusFLG;
	char buf[BUF_SIZE];
	Tree tree;

	scanf("%d",&m);
	getchar();

	for(int i = 0; i < m; i++){
		minusFLG = 1;
		fgets(buf,BUF_SIZE,stdin);
		if(buf[0] == 'i'){
			insert_data = 0;
			for(int k = 0; buf[k] != '\0';k++){
				if(buf[k] == '-') minusFLG = -1;
				if(buf[k] >= '0' && buf[k] <= '9'){
					insert_data = 10*insert_data + (buf[k] - '0');
				}
			}
			tree.insert(minusFLG*insert_data);
		}else if(buf[0] == 'p'){
			tree.print();
		}else if(buf[0] == 'f'){
			search_data = 0;
			for(int k = 0; buf[k] != '\0';k++){
				if(buf[k] == '-') minusFLG = -1;
				if(buf[k] >= '0' && buf[k] <= '9'){
					search_data = 10*search_data + (buf[k] - '0');
				}
			}
			if(tree.find(minusFLG*search_data)){
				printf("yes\n");
			}else{
				printf("no\n");
			}
		}else{
			delete_data = 0;
			for(int k = 0; buf[k] != '\0';k++){
				if(buf[k] == '-') minusFLG = -1;
				if(buf[k] >= '0' && buf[k] <= '9'){
					delete_data = 10*delete_data + (buf[k] - '0');
				}
			}
			tree.deleteNode(minusFLG*delete_data);
		}
	}
}
accuracy: 1
time_ms: 200
memory_kb: 22284
final_rank: 2

code_snippet: #include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iostream>
using namespace std;

struct Node {
    int key;
    Node *right, *left, *parent;
};

Node *root, *NIL;

Node * treeMinimum(Node *x) {
    while( x->left != NIL ) x = x->left;
    return x;
}

Node * find(Node *u, int k) {
    while( u != NIL && k != u->key ) {
        if ( k < u->key ) u = u->left;
        else u = u->right;
    }
    return u;
}

Node * treeSuccessor(Node *x) {
    if ( x->right != NIL ) return treeMinimum(x->right);
    Node *y = x->parent;
    while( y != NIL && x == y->right ) {
        x = y;
        y = y->parent;
    }
    return y;
}

void treeDelete(Node *z) {
    Node *y;
    Node *x;
    if ( z->left == NIL || z->right == NIL ) y = z;
    else y = treeSuccessor(z);
    if ( y->left != NIL ) {
        x = y->left;
    } else {
        x = y->right;
    }
    if ( x != NIL ) {
        x->parent = y->parent;
    }
    if ( y->parent == NIL ) {
        root = x;
    } else {
        if ( y == y->parent->left) {
            y->parent->left = x;
        } else {
            y->parent->right = x;
        }
    }
    if ( y != z ) {
        z->key = y->key;
    }
    free(y);
}

void insert(int k) {
    Node *y = NIL;
    Node *x = root;
    Node *z;
    z = (Node *)malloc(sizeof(Node));
    z->key = k;
    z->left = NIL;
    z->right = NIL;
    while( x != NIL ) {
        y = x;
        if ( z->key < x->key ) {
            x = x->left;
        } else {
            x = x->right;
        }
    }
    z->parent = y;
    if ( y == NIL ) {
        root = z;
    } else {
        if ( z->key < y->key ) {
            y->left = z;
        } else {
            y->right = z;
        }
    }
}

void inorder(Node *u) {
    if ( u == NIL ) return;
    inorder(u->left);
    printf(" %d", u->key);
    inorder(u->right);
}

void preorder(Node *u) {
    if ( u == NIL ) return;
    printf(" %d", u->key);
    preorder(u->left);
    preorder(u->right);
}

int main() {
    int n, i, x;
    string com;
    scanf("%d", &n);
    for ( i = 0; i < n; i++ ) {
        cin >> com;
        if ( com[0] == 'f' ) {
            scanf("%d", &x);
            Node *t = find(root, x);
            if ( t != NIL ) printf("yes\n");
            else printf("no\n");
        }   else if ( com == "insert" ) {
            scanf("%d", &x);
            insert(x);
        }   else if ( com == "print" ) {
            inorder(root);
            printf("\n");
            preorder(root);
            printf("\n");
        }   else if ( com == "delete") {
            scanf("%d", &x);
            treeDelete(find(root, x));
        }
    }
    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 22284
final_rank: 11

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>

struct Node {
    Node *parent, *left, *right;
    int key;
};

Node *NIL, *root;

Node* treeMinimum(Node *x) {
    while (x->left != NIL) x = x->left;
    return x;
}

Node* find(Node *u, int k) {
    while (u != NIL && k != u->key) {
        if (k < u->key) u = u->left;
        else u = u->right;
    }
    return u;
}

Node* treeSuccessor(Node *x) {
    if (x->right != NIL) return treeMinimum(x->right);
    Node *y = x->parent;
    while (y != NIL && x == y->right) {
        x = y;
        y = y->parent;
    }
    return y;
}

void treeDelete(Node *z) {
    Node *y, *x;
    if (z->left == NIL || z->right == NIL) {
        y = z;
    } else {
        y = treeSuccessor(z);
    }

    if (y->left != NIL) x = y->left;
    else x = y->right;

    if (x != NIL) x->parent = y->parent;

    if (y->parent == NIL) {
        root = x;
    } else if (y == y->parent->left) {
        y->parent->left = x;
    } else {
        y->parent->right = x;
    }

    if (y != z) {
        z->key = y->key;
    }

    free(y);
}

void insert(int k) {
    Node *z = (Node *)malloc(sizeof(Node));
    z->key = k;
    z->left = NIL;
    z->right = NIL;
    z->parent = NIL;

    Node *y = NIL;
    Node *x = root;

    while (x != NIL) {
        y = x;
        if (z->key < x->key) x = x->left;
        else x = x->right;
    }

    z->parent = y;
    if (y == NIL) root = z;
    else if (z->key < y->key) y->left = z;
    else y->right = z;
}

void inorder(Node *u) {
    if (u == NIL) return;
    inorder(u->left);
    printf(" %d", u->key);
    inorder(u->right);
}

void preorder(Node *u) {
    if (u == NIL) return;
    printf(" %d", u->key);
    preorder(u->left);
    preorder(u->right);
}

int main() {
    int m, x;
    char com[20];

    NIL = (Node *)malloc(sizeof(Node));
    NIL->left = NIL->right = NIL->parent = NIL;
    root = NIL;

    scanf("%d", &m);
    for (int i = 0; i < m; i++) {
        scanf("%s", com);
        if (strcmp(com, "insert") == 0) {
            scanf("%d", &x);
            insert(x);
        } else if (strcmp(com, "find") == 0) {
            scanf("%d", &x);
            Node *t = find(root, x);
            printf(t != NIL ? "yes\n" : "no\n");
        } else if (strcmp(com, "delete") == 0) {
            scanf("%d", &x);
            Node *t = find(root, x);
            if (t != NIL) treeDelete(t);
        } else if (strcmp(com, "print") == 0) {
            inorder(root);
            printf("\n");
            preorder(root);
            printf("\n");
        }
    }
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 21732
final_rank: 5