-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprefixsumset.cpp
More file actions
59 lines (54 loc) · 1.15 KB
/
Copy pathprefixsumset.cpp
File metadata and controls
59 lines (54 loc) · 1.15 KB
1
2
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
/*
Insert and remove elments from multiset.
If calls to .sum(...) do not differ
much on consecutive calls then this
is fast.
*/
struct PrefixSumSet {
multiset<int> in;
multiset<int> out;
int prefix = 1;
int insum = 0;
void rebalance() {
while (in.size() && out.size() && *in.rbegin() > *out.begin()) {
int u = *in.rbegin();
int v = *out.begin();
insum -= u;
insum += v;
in.erase(in.find(u));
out.erase(out.find(v));
in.insert(v);
out.insert(u);
}
while (in.size() > prefix) {
int delta = *in.rbegin();
insum -= delta;
in.erase(in.find(delta));
out.insert(delta);
}
while (in.size() < prefix && out.size()) {
insum += *out.begin();
in.insert(*out.begin());
out.erase(out.begin());
}
}
void add(int elem) {
in.insert(elem);
insum += elem;
rebalance();
}
void erase(int elem) {
if (in.find(elem) != in.end()) {
insum -= elem;
in.erase(in.find(elem));
} else {
out.erase(out.find(elem));
}
rebalance();
}
int sum(int num) {
prefix = num;
rebalance();
return insum;
}
};