-
Notifications
You must be signed in to change notification settings - Fork 2
/
Venice set (complete).cpp
127 lines (95 loc) · 2.58 KB
/
Venice set (complete).cpp
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
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
116
117
118
119
120
121
122
123
124
125
126
127
/*8<
@Title: Venice Set (complete)
@Description:
A container which you can insert elements
update all at once and also make a few
queries
@Usage:
\begin{compactitem}
\item $add\_element(e,q)$: adds $q$ copies
of $e$, if no $q$ is provided adds a single
one
\item $update\_all(x)$: increment every
value by $x$
\item $erase(e)$: removes every copy
of $e$, and returns how much was
removed.
\item $count(e)$: returns the number
of $e$ in the container
\item $high()$/$low()$: returns the
hightest/lowest element, and it's
quantity
\item $pop\_low(q)$/$pop\_high(q)$: removes
$q$ copies of the lowest/highest elements
if no $q$ is provided removes all copies
of the lowest/highest element.
\end{compactitem}
You may answer which is the $K-th$ value and
it's quantity using an $ordered\_set$.
Probably works with other operations
@Time:
Considering $N$ the number of distinct
numbers in the container
\begin{compactitem}
\item $add\_element(e,q)$: $O(\log{(N))}$
\item $update\_all(x)$:$O(1)$
\item $erase(e)$: $O(\log{(N))}$
\item $count(e)$: $O(\log{(N))}$
\item $high()$/$low()$: $O(1)$
\item $pop\_low(q)$/$pop\_high(q)$: worst
case is $O(N \cdot \log{(N)})$ if you
remove all elements and so on...
\end{compactitem}
@Warning:
There is no error handling if you try to
$pop$ more elements than exists or related
stuff
>8*/
struct VeniceSet {
set<pll> st;
ll acc;
VeniceSet() : acc() {}
ll add_element(ll e, ll q = 1) {
q += erase(e);
e -= acc;
st.emplace(e, q);
return q;
}
void update_all(ll x) { acc += x; }
ll erase(ll e) {
e -= acc;
auto it = st.lb({e, LLONG_MIN});
if (it == end(st) || (*it).first != e)
return 0;
ll ret = (*it).second;
st.erase(it);
return ret;
}
ll count(ll x) {
x -= acc;
auto it = st.lb({x, LLONG_MIN});
if (it == end(st) || (*it).first != x)
return 0;
return (*it).second;
}
pll high() { return *rbegin(st); }
pll low() { return *begin(st); }
void pop_high(ll q = -1) {
if (q == -1) q = high().second;
while (q) {
auto [e, eq] = high();
st.erase(prev(end(st)));
if (eq > q) add_element(e, eq - q);
q = max(0ll, q - eq);
}
}
void pop_low(ll q = -1) {
if (q == -1) q = low().second;
while (q) {
auto [e, eq] = low();
st.erase(st.begin());
if (eq > q) add_element(e, eq - q);
q = max(0ll, q - eq);
}
}
};