Skip to content

Commit 3c7ea53

Browse files
committed
LibreOJ: 6061
「2017 山东一轮集训 Day1」Sim
1 parent 0d70909 commit 3c7ea53

File tree

1 file changed

+290
-0
lines changed

1 file changed

+290
-0
lines changed

LibreOJ/6061.cpp

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
/**
2+
* @file 6061.cpp
3+
* @author Macesuted ([email protected])
4+
* @date 2022-06-04
5+
*
6+
* @copyright Copyright (c) 2022
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 100005
20+
#define mod 1000000007
21+
22+
typedef tuple<int, int, int> tiii;
23+
24+
int id[maxn << 1];
25+
26+
class FhqTreap1 {
27+
private:
28+
struct Node {
29+
Node *l, *r;
30+
int siz, id, rnk;
31+
bool ali, era;
32+
Node(int id_) { l = r = nullptr, siz = 1, ali = true, era = false, rnk = rand(), id = id_; }
33+
};
34+
35+
Node* root;
36+
int n, cnt;
37+
38+
int getSiz(Node* p) { return p ? p->siz : 0; }
39+
void clear(Node* p) { return p && (p->era = true, p->ali = false, p->siz = 0), void(); }
40+
void pushDown(Node* p) { return p->era && (clear(p->l), clear(p->r), p->era = false), void(); }
41+
void pushUp(Node* p) { return p->siz = p->ali + getSiz(p->l) + getSiz(p->r), void(); }
42+
void split(Node* p, Node*& t1, Node*& t2, int siz) {
43+
if (!p) return t1 = t2 = nullptr, void();
44+
pushDown(p);
45+
if (p->ali + getSiz(p->l) <= siz)
46+
t1 = p, split(p->r, t1->r, t2, siz - p->ali - getSiz(p->l));
47+
else
48+
t2 = p, split(p->l, t1, t2->l, siz);
49+
return pushUp(p);
50+
}
51+
void merge(Node*& p, Node* t1, Node* t2) {
52+
if (!t1) return p = t2, void();
53+
if (!t2) return p = t1, void();
54+
if (t1->rnk < t2->rnk)
55+
pushDown(p = t1), merge(p->r, t1->r, t2);
56+
else
57+
pushDown(p = t2), merge(p->l, t1, t2->l);
58+
return pushUp(p);
59+
}
60+
void getId(Node* p) {
61+
if (!p) return;
62+
return getId(p->l), id[p->id] = ++cnt, getId(p->r), delete p;
63+
}
64+
65+
public:
66+
FhqTreap1(void) { root = nullptr; }
67+
void build(int n_) {
68+
n = n_;
69+
for (int i = 1; i <= n; i++) merge(root, root, new Node(i));
70+
return;
71+
}
72+
void insert(int p) {
73+
Node* tr = nullptr;
74+
return split(root, root, tr, p), merge(root, root, new Node(++n)), merge(root, root, tr);
75+
}
76+
void erase(int p) {
77+
Node *tp = nullptr, *tr = nullptr;
78+
split(root, root, tp, p - 1), split(tp, tp, tr, 1), clear(tp);
79+
return merge(root, root, tp), merge(root, root, tr);
80+
}
81+
void getId(void) { return cnt = 0, getId(root); }
82+
};
83+
84+
class FhqTreap2 {
85+
private:
86+
struct Node {
87+
Node *l, *r;
88+
int siz, rnk, id;
89+
Node(int id_) { l = r = nullptr, siz = 1, rnk = rand(), id = id_; }
90+
};
91+
92+
Node* root;
93+
94+
int getSiz(Node* p) { return p ? p->siz : 0; }
95+
void pushUp(Node* p) { return p->siz = 1 + getSiz(p->l) + getSiz(p->r), void(); }
96+
void split(Node* p, Node*& t1, Node*& t2, int siz) {
97+
if (!p) return t1 = t2 = nullptr, void();
98+
if (1 + getSiz(p->l) <= siz)
99+
t1 = p, split(p->r, t1->r, t2, siz - 1 - getSiz(p->l));
100+
else
101+
t2 = p, split(p->l, t1, t2->l, siz);
102+
return pushUp(p);
103+
}
104+
void merge(Node*& p, Node* t1, Node* t2) {
105+
if (!t1) return p = t2, void();
106+
if (!t2) return p = t1, void();
107+
if (t1->rnk < t2->rnk)
108+
p = t1, merge(p->r, t1->r, t2);
109+
else
110+
p = t2, merge(p->l, t1, t2->l);
111+
return pushUp(p);
112+
}
113+
114+
public:
115+
FhqTreap2(void) { root = nullptr; }
116+
void insert(int p, int v) {
117+
Node* tr = nullptr;
118+
return split(root, root, tr, p), merge(root, root, new Node(v)), merge(root, root, tr);
119+
}
120+
void erase(int p) {
121+
Node *tp = nullptr, *tr = nullptr;
122+
split(root, root, tp, p - 1), split(tp, tp, tr, 1), delete tp;
123+
return merge(root, root, tr);
124+
}
125+
int getId(int p) {
126+
Node *tp = nullptr, *tr = nullptr;
127+
split(root, root, tp, p - 1), split(tp, tp, tr, 1);
128+
int ret = tp->id;
129+
return merge(root, root, tp), merge(root, root, tr), ret;
130+
}
131+
};
132+
133+
class FenwickTree {
134+
private:
135+
struct Value {
136+
int64_t v1, v2, v3;
137+
int cnt;
138+
Value(void) { v1 = v2 = v3 = cnt = 0; }
139+
Value(int v) { v1 = v, v2 = v3 = 0, cnt = 1; }
140+
Value(int64_t v1_, int64_t v2_, int64_t v3_, int cnt_) { v1 = v1_, v2 = v2_, v3 = v3_, cnt = cnt_; }
141+
Value operator+(const Value& o) const {
142+
return Value{(v1 + o.v1) % mod, (v2 + v1 * o.v1 + o.v2) % mod, (v3 + v2 * o.v1 + v1 * o.v2 + o.v3) % mod,
143+
cnt + o.cnt};
144+
}
145+
};
146+
147+
class SegmentTree {
148+
private:
149+
struct Node {
150+
Node *l, *r;
151+
Value val;
152+
Node(void) { l = r = nullptr; }
153+
};
154+
155+
Node* root;
156+
int n;
157+
158+
void pushUp(Node* p) { return p->val = (p->l ? p->l->val : Value()) + (p->r ? p->r->val : Value()), void(); }
159+
void insert(Node*& p, int l, int r, int qp, int v) {
160+
if (!p) p = new Node();
161+
if (l == r) return p->val = Value(v), void();
162+
int mid = (l + r) >> 1;
163+
qp <= mid ? insert(p->l, l, mid, qp, v) : insert(p->r, mid + 1, r, qp, v);
164+
return pushUp(p);
165+
}
166+
void erase(Node*& p, int l, int r, int qp) {
167+
if (l == r) return delete p, p = nullptr, void();
168+
int mid = (l + r) >> 1;
169+
qp <= mid ? erase(p->l, l, mid, qp) : erase(p->r, mid + 1, r, qp);
170+
pushUp(p);
171+
if (!p->val.cnt) delete p, p = nullptr;
172+
return;
173+
}
174+
Value query(Node* p, int l, int r, int ql, int qr) {
175+
if (!p) return Value();
176+
if (ql <= l && r <= qr) return p->val;
177+
int mid = (l + r) >> 1;
178+
if (qr <= mid) return query(p->l, l, mid, ql, qr);
179+
if (ql > mid) return query(p->r, mid + 1, r, ql, qr);
180+
return query(p->l, l, mid, ql, qr) + query(p->r, mid + 1, r, ql, qr);
181+
}
182+
183+
public:
184+
SegmentTree(void) { root = nullptr; }
185+
void resize(int n_) { return n = n_, void(); }
186+
void insert(int p, int v) { return insert(root, 1, n, p, v); }
187+
void erase(int p) { return erase(root, 1, n, p); }
188+
Value query(int l, int r) { return query(root, 1, n, l, r); }
189+
};
190+
191+
SegmentTree tree[maxn << 1];
192+
int n;
193+
194+
Value query(int xl, int xr, int yr) {
195+
Value ans;
196+
for (int i = yr; i; i -= i & -i) ans = ans + tree[i].query(xl, xr);
197+
return ans;
198+
}
199+
200+
public:
201+
void build(int n_) {
202+
n = n_;
203+
for (int i = 1; i <= n; i++) tree[i].resize(n);
204+
return;
205+
}
206+
void insert(int x, int y, int v) {
207+
for (int i = y + 1; i <= n; i += i & -i) tree[i].insert(x, v);
208+
return;
209+
}
210+
void erase(int x, int y) {
211+
for (int i = y + 1; i <= n; i += i & -i) tree[i].erase(x);
212+
return;
213+
}
214+
int64_t querySum(int xl, int xr, int yr) { return query(xl, xr, yr + 1).v3; }
215+
int64_t queryCnt(int xl, int xr, int yr) { return query(xl, xr, yr + 1).cnt; }
216+
};
217+
218+
FhqTreap1 BT1;
219+
FhqTreap2 BT2;
220+
FenwickTree FT;
221+
int a[maxn], v[maxn << 1];
222+
tiii ques[maxn];
223+
map<int, set<int>> pos;
224+
225+
int getLeft(int x) {
226+
auto p = pos[v[x]].find(x);
227+
return p == pos[v[x]].begin() ? 0 : *--p;
228+
}
229+
int getRight(int x) {
230+
auto p = pos[v[x]].find(x);
231+
return ++p == pos[v[x]].end() ? 0 : *p;
232+
}
233+
void insert(int x) {
234+
pos[v[x]].insert(x);
235+
int l = getLeft(x), r = getRight(x);
236+
FT.insert(x, l, v[x]);
237+
if (r) FT.erase(r, l), FT.insert(r, x, v[r]);
238+
return;
239+
}
240+
void erase(int x) {
241+
int l = getLeft(x), r = getRight(x);
242+
pos[v[x]].erase(x);
243+
FT.erase(x, l);
244+
if (r) FT.erase(r, x), FT.insert(r, l, v[r]);
245+
return;
246+
}
247+
248+
void solve(void) {
249+
int n, q;
250+
cin >> n >> q;
251+
int tn = n;
252+
for (int i = 1; i <= n; i++) cin >> a[i];
253+
for (int i = 1; i <= q; i++) {
254+
cin >> get<0>(ques[i]) >> get<1>(ques[i]);
255+
if (get<0>(ques[i]) != 3) cin >> get<2>(ques[i]);
256+
}
257+
BT1.build(n);
258+
for (int i = 1; i <= q; i++) {
259+
if (get<0>(ques[i]) == 3) BT1.erase(get<1>(ques[i]));
260+
if (get<0>(ques[i]) == 4) BT1.insert(get<1>(ques[i])), n++;
261+
}
262+
BT1.getId(), FT.build(n);
263+
for (int i = 1; i <= tn; i++) v[id[i]] = a[i], insert(id[i]), BT2.insert(i - 1, id[i]);
264+
for (int i = 1, t, x, y, c = tn; i <= q; i++) {
265+
tie(t, x, y) = ques[i];
266+
if (t == 1) x = BT2.getId(x), y = BT2.getId(y), cout << FT.querySum(x, y, x - 1) << endl;
267+
if (t == 2) x = BT2.getId(x), erase(x), v[x] = y, insert(x);
268+
if (t == 3) x = BT2.getId(x), erase(x), BT2.erase(get<1>(ques[i]));
269+
if (t == 4) v[x = id[++c]] = y, insert(x), BT2.insert(get<1>(ques[i]), x);
270+
if (t == 5) x = BT2.getId(x), y = BT2.getId(y), cout << FT.queryCnt(x, y, x - 1) << endl;
271+
}
272+
return;
273+
}
274+
275+
bool mem2;
276+
277+
int main() {
278+
ios::sync_with_stdio(false), cin.tie(nullptr);
279+
#ifdef LOCAL
280+
cerr << "Memory Cost: " << abs(&mem1 - &mem2) / 1024. / 1024. << "MB" << endl;
281+
#endif
282+
283+
int _ = 1;
284+
while (_--) solve();
285+
286+
#ifdef LOCAL
287+
cerr << "Time Cost: " << clock() * 1000. / CLOCKS_PER_SEC << "MS" << endl;
288+
#endif
289+
return 0;
290+
}

0 commit comments

Comments
 (0)