1
+ /* *
2
+ * @file 106.cpp
3
+ * @author Macesuted ([email protected] )
4
+ * @date 2023-03-02
5
+ *
6
+ * @copyright Copyright (c) 2023
7
+ *
8
+ */
9
+
10
+ #include < bits/stdc++.h>
11
+ using namespace std ;
12
+
13
+ #ifndef LOCAL
14
+ #define endl ' \n '
15
+ #endif
16
+
17
+ bool mem1;
18
+
19
+ #define maxn 50005
20
+
21
+ mt19937 rnd (20080618 );
22
+
23
+ class FhqTreap {
24
+ private:
25
+ struct Node {
26
+ Node *l, *r;
27
+ int rnk, siz, val;
28
+ Node (int _val) { l = r = nullptr , rnk = rnd (), siz = 1 , val = _val; }
29
+ };
30
+
31
+ Node* root;
32
+
33
+ int getSiz (Node* p) { return p ? p->siz : 0 ; }
34
+ void pushUp (Node* p) { return p->siz = getSiz (p->l ) + getSiz (p->r ) + 1 , void (); }
35
+ void split (Node* p, Node*& t1, Node*& t2, int v) {
36
+ if (!p) return t1 = t2 = nullptr , void ();
37
+ if (p->val < v)
38
+ t1 = p, split (p->r , t1->r , t2, v);
39
+ else
40
+ t2 = p, split (p->l , t1, t2->l , v);
41
+ return pushUp (p);
42
+ }
43
+ void merge (Node*& p, Node* t1, Node* t2) {
44
+ if (!t1) return p = t2, void ();
45
+ if (!t2) return p = t1, void ();
46
+ if (t1->rnk < t2->rnk )
47
+ p = t1, merge (p->r , t1->r , t2);
48
+ else
49
+ p = t2, merge (p->l , t1, t2->l );
50
+ return pushUp (p);
51
+ }
52
+
53
+ public:
54
+ FhqTreap (void ) { root = nullptr ; }
55
+ void insert (int v) {
56
+ Node* tr = nullptr ;
57
+ split (root, root, tr, v);
58
+ return merge (root, root, new Node (v)), merge (root, root, tr);
59
+ }
60
+ void erase (int v) {
61
+ Node *tp = nullptr , *tr = nullptr ;
62
+ split (root, root, tp, v), split (tp, tp, tr, v + 1 );
63
+ return delete tp, merge (root, root, tr);
64
+ }
65
+ int query (int l, int r) {
66
+ Node *tp = nullptr , *tr = nullptr ;
67
+ split (root, root, tp, l), split (tp, tp, tr, r + 1 );
68
+ int ret = getSiz (tp);
69
+ return merge (root, root, tp), merge (root, root, tr), ret;
70
+ }
71
+ };
72
+ class SegmentTree {
73
+ private:
74
+ struct Node {
75
+ Node *l, *r;
76
+ FhqTreap FT;
77
+ Node (void ) { l = r = nullptr ; }
78
+ };
79
+
80
+ Node* root;
81
+
82
+ void update (Node*& p, int l, int r, int v, int w) {
83
+ if (!p) p = new Node ();
84
+ w > 0 ? p->FT .insert (w) : p->FT .erase (-w);
85
+ if (l == r) return ;
86
+ int mid = (l + r) >> 1 ;
87
+ v <= mid ? update (p->l , l, mid, v, w) : update (p->r , mid + 1 , r, v, w);
88
+ }
89
+ int query (Node*& p, int l, int r) { return p ? p->FT .query (l, r) : 0 ; }
90
+ int query1 (Node*& p, int l, int r, int v, int ql, int qr) {
91
+ if (!p) return 0 ;
92
+ if (v >= r) return query (p, ql, qr);
93
+ int mid = (l + r) >> 1 ;
94
+ return v <= mid ? query1 (p->l , l, mid, v, ql, qr) : query (p->l , ql, qr) + query1 (p->r , mid + 1 , r, v, ql, qr);
95
+ }
96
+ int query2 (Node*& p, int l, int r, int v, int ql, int qr) {
97
+ if (l == r) return l;
98
+ int mid = (l + r) >> 1 , vl = query (p->l , ql, qr);
99
+ return vl >= v ? query2 (p->l , l, mid, v, ql, qr) : query2 (p->r , mid + 1 , r, v - vl, ql, qr);
100
+ }
101
+ int query4 (Node*& p, int l, int r, int v, int ql, int qr) {
102
+ if (!query (p, ql, qr)) return INT_MIN;
103
+ if (l == r) return l;
104
+ int mid = (l + r) >> 1 , ret = INT_MIN;
105
+ if (mid + 1 < v) ret = query4 (p->r , mid + 1 , r, v, ql, qr);
106
+ return ret != INT_MIN ? ret : query4 (p->l , l, mid, v, ql, qr);
107
+ }
108
+ int query5 (Node*& p, int l, int r, int v, int ql, int qr) {
109
+ if (!query (p, ql, qr)) return INT_MAX;
110
+ if (l == r) return l;
111
+ int mid = (l + r) >> 1 , ret = INT_MAX;
112
+ if (mid > v) ret = query5 (p->l , l, mid, v, ql, qr);
113
+ return ret != INT_MAX ? ret : query5 (p->r , mid + 1 , r, v, ql, qr);
114
+ }
115
+
116
+ public:
117
+ SegmentTree (void ) { root = nullptr ; }
118
+ void update (int p, int v) { return update (root, -1e8 , +1e8 , v, p); }
119
+ int query1 (int l, int r, int v) { return query1 (root, -1e8 , +1e8 , v - 1 , l, r) + 1 ; }
120
+ int query2 (int l, int r, int v) { return query2 (root, -1e8 , +1e8 , v, l, r); }
121
+ int query4 (int l, int r, int v) { return query4 (root, -1e8 , +1e8 , v, l, r); }
122
+ int query5 (int l, int r, int v) { return query5 (root, -1e8 , +1e8 , v, l, r); }
123
+ } ST;
124
+
125
+ int a[maxn];
126
+
127
+ void solve (void ) {
128
+ int n, q;
129
+ cin >> n >> q;
130
+ for (int i = 1 ; i <= n; i++) cin >> a[i], ST.update (i, a[i]);
131
+ while (q--) {
132
+ int op;
133
+ cin >> op;
134
+ if (op == 1 ) {
135
+ int l, r, x;
136
+ cin >> l >> r >> x, cout << ST.query1 (l, r, x) << endl;
137
+ } else if (op == 2 ) {
138
+ int l, r, k;
139
+ cin >> l >> r >> k, cout << ST.query2 (l, r, k) << endl;
140
+ } else if (op == 3 ) {
141
+ int p, x;
142
+ cin >> p >> x, ST.update (-p, a[p]), ST.update (p, a[p] = x);
143
+ } else if (op == 4 ) {
144
+ int l, r, x;
145
+ cin >> l >> r >> x, cout << ST.query4 (l, r, x) << endl;
146
+ } else {
147
+ int l, r, x;
148
+ cin >> l >> r >> x, cout << ST.query5 (l, r, x) << endl;
149
+ }
150
+ }
151
+ return ;
152
+ }
153
+
154
+ bool mem2;
155
+
156
+ int main () {
157
+ ios::sync_with_stdio (false ), cin.tie (nullptr );
158
+ #ifdef LOCAL
159
+ cerr << " Memory Cost: " << abs (&mem1 - &mem2) / 1024 . / 1024 . << " MB" << endl;
160
+ #endif
161
+
162
+ int _ = 1 ;
163
+ while (_--) solve ();
164
+
165
+ #ifdef LOCAL
166
+ cerr << " Time Cost: " << clock () * 1000 . / CLOCKS_PER_SEC << " MS" << endl;
167
+ #endif
168
+ return 0 ;
169
+ }
0 commit comments