Problem:
Set: Range 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).

delete($x$): Delete $x$ from $S$.

dump($L$, $R$): Print elements $x$ in $S$ such that $L \leq x \leq R$.

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$

or

2 $x$

or

3 $L$ $R$

where the first digits 0, 1, 2 and 3 represent insert, find, delete and dump 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$.

For each dump operation, print the corresponding elements in ascending order. Print an element in a line.

Constraints

$1 \leq q \leq 200,000$

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

The total number of elements printed by dump operations does not exceed $1,000,000$

Sample Input 1

9
0 1
0 2
0 3
2 2
1 1
1 2
1 3
0 4
3 2 4

Sample Output 1

1
2
3
1
0
1
3
3
4

Solution in C (judge verdict: Accepted)

#include <stdio.h>

unsigned xor128() {
	static unsigned x = 123456789, y = 362436069, z = 521288629, w = 88675123;
	unsigned t = x ^ (x << 11);
	x = y; y = z; z = w;
	return w = w ^ (w >> 19) ^ (t ^ (t >> 8));
}

typedef struct node_t {
	int val;
	struct node_t *lch, *rch;
	int size;
	unsigned int pri;
} node;

node* new_node(int val) {
	static int it = 0;
	static node pool[200000];
	pool[it] = (node) { val, 0, 0, 1, xor128() };
	return &pool[it++];
}

int count(node *t) {
	return !t ? 0 : t->size;
}

node *update(node *t) {
	t->size = count(t->lch) + count(t->rch) + 1;
	return t;
}

node *merge(node *l, node *r) {
	if (!l || !r) return !l ? r : l;
	if (l->pri > r->pri) {
		l->rch = merge(l->rch, r);
		return update(l);
	}
	r->lch = merge(l, r->lch);
	return update(r);
}

typedef struct{ node *a, *b; } pnode;

pnode split(node *t, int k) {
	if (!t) return (pnode) { 0, 0 };
	if (k <= count(t->lch)) {
		pnode s = split(t->lch, k);
		t->lch = s.b;
		return (pnode) { s.a, update(t) };
	}
	pnode s = split(t->rch, k - count(t->lch) - 1);
	t->rch = s.a;
	return (pnode) { update(t), s.b };
}

node* find(node *t, int val) {
	while (t) {
		if (t->val == val) break;
		t = val < t->val ? t->lch : t->rch;
	}
	return t;
}

int count_lower(node *t, int v) {
	if (!t) return 0;
	if (t->val < v) return count(t->lch) + 1 + count_lower(t->rch, v);
	if (t->val == v) return count(t->lch);
	return count_lower(t->lch, v);
}

node *insert(node *t, int val) {
	int k = count_lower(t, val);
	pnode s = split(t, k);
	return merge(merge(s.a, new_node(val)), s.b);
}

node *erase(node *t, int k) {
	pnode s1 = split(t, k), s2 = split(s1.b, 1);
	return merge(s1.a, s2.b);
}

void print(node *t) {
	if (!t) return;
	print(t->lch);
	printf("%d\n", t->val);
	print(t->rch);
}

int main(void)
{
	int q, com, x, l, r, cnt = 0;
	node *root = 0;
	pnode p1, p2;
	scanf("%d", &q);
	while (q--) {
		scanf("%d%d", &com, &x);
		if (com == 0) {
			if (!find(root, x)) ++cnt, root = insert(root, x);
			printf("%d\n", cnt);
		}
		else if (com == 1) {
			puts(find(root, x) ? "1" : "0");
		}
		else if (com == 2) {
			if (find(root, x)) --cnt, root = erase(root, count_lower(root, x));
		}
		else {
			scanf("%d", &r);
			l = count_lower(root, x);
			r = count_lower(root, r + 1);
			p1 = split(root, l), p2 = split(p1.b, r - l);
			print(p2.a);
			root = merge(merge(p1.a, p2.a), p2.b);
		}
	}
	return 0;
}