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 Haskell (judge verdict: Memory Limit Exceeded)

import Control.Applicative ((<$>))
import Control.Monad.State
import Data.Monoid

data Tree a = Nill | Tree a (Tree a) (Tree a) deriving (Show)
newtype DList a = DList { unDL :: [a] -> [a] }

main = do
        n <- readLn
        evalStateT (query n) Nill

insert :: Ord a => a -> Tree a -> Tree a
insert x Nill = Tree x Nill Nill
insert x (Tree y l r)
    | x < y = Tree y (insert x l) r
    | x > y = Tree y l (insert x r)
    | otherwise = Tree y l r

searchITW tree = fromDList $ sitw tree

sitw Nill = mempty
sitw (Tree x l r) = sitw l `mappend` toDList [x] `mappend` sitw r

searchPTW tree = fromDList $ sptw tree

sptw Nill = mempty
sptw (Tree x l r) = toDList [x] `mappend` sptw l `mappend` sptw r

find :: Ord a => a -> Tree a -> Bool
find x Nill = False
find x (Tree y l r)
    | x > y = find x r
    | x < y = find x l
    | x == y = True

type Query s = StateT s IO ()

query n
    | n == 0 = return ()
    | otherwise = do
        inp <- liftIO $ words<$>getLine
        case head inp of
            "insert" -> let x = read (inp !! 1) :: Int in qInsert x >> query (n-1)
            "print"  -> qPrint >> query (n-1)
            "find"   -> let x = read (inp !! 1) :: Int in qFind x >> query (n-1)
            _        -> return ()

qInsert :: Ord a => a -> Query (Tree a)
qInsert x = modify (insert x)
qPrint = do
        t <- get
        liftIO $ putStrLn.(" "++).unwords.map show $ searchITW t
        liftIO $ putStrLn.(" "++).unwords.map show $ searchPTW t
qFind :: Ord a => a -> Query (Tree a)
qFind x = do
        t <- get
        if find x t then liftIO $ putStrLn "yes"
                    else liftIO $ putStrLn "no"


toDList :: [a] -> DList a
toDList xs = DList (xs++)

fromDList (DList f) = f []

instance Monoid (DList a) where
        mempty  = DList (\xs -> [] ++ xs)
        (DList f) `mappend` (DList g) = DList (\xs -> f (g xs))