| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 
 | const int INF = 0x3f3f3f3f;struct node {
 int l, r, val, siz, rnd, cnt;
 } p[maxn];
 int cnt;
 
 inline void update(int id) {
 p[id].siz = p[p[id].l].siz + p[p[id].r].siz + p[id].cnt;
 }
 
 void rturn(int &k) {
 int tmp = p[k].l;
 p[k].l = p[tmp].r;
 p[tmp].r = k;
 p[tmp].siz = p[k].siz;
 update(k);
 k = tmp;
 }
 
 void lturn(int &k) {
 int tmp = p[k].r;
 p[k].r = p[tmp].l;
 p[tmp].l = k;
 p[tmp].siz = p[k].siz;
 update(k);
 k = tmp;
 }
 
 void insert(int &id, int val) {
 if (!id) {
 id = ++cnt;
 p[id].siz = 1;
 p[id].cnt = 1;
 p[id].val = val;
 p[id].rnd = rand();
 return;
 }
 p[id].siz++;
 if (p[id].val == val)
 p[id].cnt++;
 else if (p[id].val < val) {
 insert(p[id].r, val);
 if (p[p[id].r].rnd < p[id].rnd)
 lturn(id);
 } else {
 insert(p[id].l, val);
 if (p[p[id].l].rnd < p[id].rnd)
 rturn(id);
 }
 }
 
 void del(int &id, int val) {
 if (!id)
 return;
 if (p[id].val == val) {
 if (p[id].cnt > 1) {
 p[id].cnt--;
 p[id].siz--;
 } else {
 if (p[id].l == 0 || p[id].r == 0)
 id = p[id].l + p[id].r;
 else if (p[p[id].l].rnd < p[p[id].r].rnd) {
 rturn(id);
 del(id, val);
 } else {
 lturn(id);
 del(id, val);
 }
 }
 } else if (val > p[id].val) {
 p[id].siz--;
 del(p[id].r, val);
 } else {
 p[id].siz--;
 del(p[id].l, val);
 }
 }
 
 int find_rank(int id, int val) {
 if (id == 0)
 return 0;
 if (p[id].val == val)
 return p[p[id].l].siz + 1;
 else if (p[id].val < val)
 return p[p[id].l].siz + p[id].cnt + find_rank(p[id].r, val);
 else
 return find_rank(p[id].l, val);
 }
 
 int kth(int id, int k) {
 if (k <= p[p[id].l].siz)
 return kth(p[id].l, k);
 else if (k > p[p[id].l].siz + p[id].cnt)
 return kth(p[id].r, k - (p[p[id].l].siz + p[id].cnt));
 else
 return p[id].val;
 }
 
 int pre(int id, int val) {
 if (!id)
 return -INF;
 if (p[id].val >= val)
 return pre(p[id].l, val);
 else
 return max(p[id].val, pre(p[id].r, val));
 }
 
 int nxt(int id, int val) {
 if (!id)
 return INF;
 if (p[id].val <= val)
 return nxt(p[id].r, val);
 else
 return min(p[id].val, nxt(p[id].l, val));
 }
 
 |