Problem:
Set: Search

For a set $S$ of integers, perform a sequence of the following operations. Note that each value in $S$ must be unique.

insert($x$): Insert $x$ to $S$ and report the number of elements in $S$ after the operation.

find($x$): Report the number of $x$ in $S$ (0 or 1).

Input

The input is given in the following format.

$q$
$query_1$
$query_2$
:
$query_q$

Each query $query_i$ is given by

0 $x$

or

1 $x$

where the first digits 0 and 1 represent insert and find operations respectively.

Output

For each insert operation, print the number of elements in $S$.

For each find operation, print the number of specified elements in $S$.

Constraints

$1 \leq q \leq 200,000$

$0 \leq x \leq 1,000,000,000$

Sample Input 1

7
0 1
0 2
0 3
0 2
0 4
1 3
1 10

Sample Output 1

1
2
3
3
4
1
0

Solution in Go (judge verdict: Accepted)

package main

import (
	"math/rand"
	"bufio"
	"os"
	"strconv"
)

type Comparable interface {
	less(Comparable) bool
}

type elem_t Comparable
type count_t uint
type pri_t float32
func generateRandomPriority() pri_t {
	return pri_t(rand.Float32())
}

type Node struct {
	elem     elem_t
	lch, rch *Node
	cnt      count_t
	pri      pri_t
}

func NewNode(elem elem_t) *Node {
	node := new(Node)
	node.elem = elem
	node.pri = generateRandomPriority()
	node.cnt = 1
	return node
}

func (node *Node) count() count_t {
	if node != nil {
		return node.cnt
	} else {
		return 0
	}
}

func (node *Node) update() *Node {
	node.cnt = node.lch.count() + node.rch.count() + 1;
	return node
}

func (l *Node) merge(r *Node) *Node {
	if l == nil {
		return r
	} else if r == nil {
		return l
	}

	l.update()
	r.update()
	if (l.pri > r.pri) {
		l.rch = l.rch.merge(r)
		return l.update()
	} else {
		r.lch = l.merge(r.lch)
		return r.update()
	}
}

func (node *Node) split(elem elem_t, includeToRight bool) (*Node, *Node) {
	if node == nil {
		return nil, nil
	}
	node.update()

	if includeToRight {
		if node.elem.less(elem) {
			l, r := node.rch.split(elem, includeToRight)
			node.rch = l
			return node.update(), r
		} else {
			l, r := node.lch.split(elem, includeToRight)
			node.lch = r
			return l, node.update()
		}
	} else {
		if elem.less(node.elem) {
			l, r := node.lch.split(elem, includeToRight)
			node.lch = r
			return l, node.update()
		} else {
			l, r := node.rch.split(elem, includeToRight)
			node.rch = l
			return node.update(), r
		}
	}
}

func (node *Node) insert(elem elem_t) *Node {
	c, r := node.split(elem, false)
	l, _ := c.split(elem, true)
	return l.merge(NewNode(elem).merge(r))
}

func (node *Node) erase(elem elem_t) (*Node, *Node) {
	c, r := node.split(elem, false)
	l, _ := c.split(elem, true)
	return l.merge(r), c
}

func (node *Node) find(elem elem_t) *Node {
	if node == nil {
		return nil
	}
	if node.elem.less(elem) {
		return node.rch.find(elem)
	} else if elem.less(node.elem) {
		return node.lch.find(elem)
	} else {
		return node
	}
}


type Set struct {
	root *Node
}

func (set *Set) size() count_t {
	return set.root.count()
}

func (set *Set) insert(elem elem_t) {
	set.root = set.root.insert(elem)
}

func (set *Set) erase(elem elem_t) {
	set.root, _ = set.root.erase(elem)
}

func (set *Set) find(elem elem_t) *Node {
	return set.root.find(elem)
}

type Int int

func (item Int) less(other Comparable) bool {
	otherT, ok := other.(Int)
	if !ok {
		//handle error (other was not of type T)
	}
	return item < otherT
}

var sc = bufio.NewScanner(os.Stdin)
var ou = bufio.NewWriter(os.Stdout)

func main() {
	rand.Seed(2)
	var q int
	sc.Split(bufio.ScanWords)
	sc.Scan()
	q, _ = strconv.Atoi(sc.Text())

	t := make([]int, q)
	x := make([]int, q)

	for i := 0; i < q; i++ {
		sc.Scan()
		t[i], _ = strconv.Atoi(sc.Text())
		sc.Scan()
		x[i], _ = strconv.Atoi(sc.Text())
	}

	set := new(Set)
	result := make([]int, 0)
	for i := 0; i < q; i++ {
		if t[i] == 0 {
			set.insert(Int(x[i]))
			result = append(result, int(set.size()))
		} else {
			if set.find(Int(x[i])) == nil {
				result = append(result, 0)
			} else {
				result = append(result, 1)
			}
		}
		// set.show()
	}

	for _, res := range result {
		ou.WriteString(strconv.Itoa(res) + "\n")
	}
	ou.Flush()
}