Problem:
Binary Search Tree II

Write a program which performs the following operations to a binary search tree $T$ by adding the find operation to A: Binary Search Tree I.

insert $k$: Insert a node containing $k$ as key into $T$.

find $k$: Report whether $T$ has a node containing $k$.

print: Print the keys of the binary search tree by inorder tree walk and preorder tree walk respectively.

Input

In the first line, the number of operations $m$ is given. In the following $m$ lines, operations represented by insert $k$, find $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

10
insert 30
insert 88
insert 12
insert 1
insert 20
find 12
insert 17
insert 25
find 16
print

Sample Output 1

yes
no
1 12 17 20 25 30 88
30 12 1 20 17 25 88

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution in Rust (judge verdict: Accepted)

#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::io::{stdin, stdout, Read, Write};
use std::str::FromStr;

#[derive(Default)]
struct Scanner<R: Read> {
    reader: R,
}

impl<R: Read> Scanner<R> {
    fn new(reader: R) -> Scanner<R> {
        Scanner { reader }
    }

    fn scan<T: FromStr>(&mut self) -> Option<T> {
        let s = self
            .reader
            .by_ref()
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect::<String>();
        s.parse::<T>().ok()
    }

    fn next<T: FromStr>(&mut self) -> T {
        if let Some(s) = self.scan() {
            s
        } else {
            std::process::exit(1);
        }
    }
}

struct Tree {
    nodes: Vec<TreeNode>,
    root: usize,
}

struct TreeNode {
    key: i32,
    left: usize,
    right: usize,
    parent: usize,
}

impl Tree {
    fn insert(&mut self, z: i32) {
        let i = self.nodes.len();
        let mut z = TreeNode{key: z, left: i, right: i, parent: i};

        if i == 0 {
            self.root = 0;
            self.nodes.push(z);
            return;
        }

        let mut y;
        let mut x = self.root;
        loop {
            y = x;
            if z.key < self.nodes[x].key {
                if self.nodes[x].left == x {
                    break;
                }
                x = self.nodes[x].left;
            } else {
                if self.nodes[x].right == x {
                    break;
                }
                x = self.nodes[x].right;
            }
        }
        z.parent = y;
        if z.key < self.nodes[y].key {
            self.nodes[y].left = i;
        } else {
            self.nodes[y].right = i;
        }

        self.nodes.push(z);
    }

    fn find(&self, x: i32) -> bool {
        self.find_helper(self.root, x)
    }

    fn find_helper(&self, i: usize, x: i32) -> bool {
        let k = self.nodes[i].key;        
        // match x {
        //     x => true,
        //     ..k => self.nodes[i].left == i && self.find_helper(self.nodes[i].left, x),
        //     k.. => self.nodes[i].right == i && self.find_helper(self.nodes[i].right, x),
        // }
        if k == x {
            true
        } else if x < k && self.nodes[i].left != i {
            self.find_helper(self.nodes[i].left, x)
        } else if x > k && self.nodes[i].right != i {
            self.find_helper(self.nodes[i].right, x)
        } else {
            false
        }
    }

    fn print<T: Write>(&self, out: &mut T) {
        self.print_inorder(self.root, out);
        writeln!(out).ok();
        self.print_preorder(self.root, out);
        writeln!(out).ok();
    }

    fn print_inorder<W: Write>(&self, i: usize, out: &mut W) {
        if self.nodes[i].left != i {
            self.print_inorder(self.nodes[i].left, out);
        }
        write!(out, " {}", self.nodes[i].key).ok();
        if self.nodes[i].right != i {
            self.print_inorder(self.nodes[i].right, out);
        }
    }

    fn print_preorder<W: Write>(&self, i: usize, out: &mut W) {
        write!(out, " {}", self.nodes[i].key).ok();
        if self.nodes[i].left != i {
            self.print_preorder(self.nodes[i].left, out);
        }
        if self.nodes[i].right != i {
            self.print_preorder(self.nodes[i].right, out);
        }
    }
}

fn main() {
    let cin = stdin();
    let cin = cin.lock();
    let mut sc = Scanner::new(cin);
    let out = stdout();
    let mut out = out.lock();

    let n = sc.next();
    let mut t = Tree{nodes: Vec::new(), root: 0};
    for _ in 0..n {
        let op: String = sc.next();
        match op.as_str() {
            "insert" => t.insert(sc.next()),
            "print" => t.print(&mut out),
            "find" => {
                if t.find(sc.next()) {
                    writeln!(out, "yes").ok();
                } else {
                    writeln!(out, "no").ok();
                }
            },
            _  => panic!("unknown operatiion {}", op),
        }
    }
}