competitive/data_structure/
line_set.rs1use super::Bounded;
2use std::{
3 borrow::Borrow,
4 cmp::Ordering,
5 collections::BTreeSet,
6 fmt::{self, Debug},
7 ops::{Add, Div, Mul, Sub},
8};
9
10#[derive(Clone, Copy, Default, PartialEq, Eq)]
11struct Slope<T>(T);
12
13impl<T> Debug for Slope<T>
14where
15 T: Debug,
16{
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 self.0.fmt(f)
19 }
20}
21
22impl<T> PartialOrd for Slope<T>
23where
24 T: PartialOrd,
25{
26 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
27 self.0.partial_cmp(&other.0).map(|ord| ord.reverse())
28 }
29}
30
31impl<T> Ord for Slope<T>
32where
33 T: Ord,
34{
35 fn cmp(&self, other: &Self) -> Ordering {
36 self.0.cmp(&other.0).reverse()
37 }
38}
39
40#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
41struct Query<T>(T);
42
43impl<T> Debug for Query<T>
44where
45 T: Debug,
46{
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 self.0.fmt(f)
49 }
50}
51
52#[derive(Debug, Clone, Default)]
53struct Line<T> {
54 a: Slope<T>,
55 b: T,
56 q: Query<T>,
57}
58
59impl<T> PartialEq for Line<T>
60where
61 T: PartialEq,
62{
63 fn eq(&self, other: &Self) -> bool {
64 self.a == other.a
65 }
66}
67
68impl<T> Eq for Line<T> where T: Eq {}
69
70impl<T> PartialOrd for Line<T>
71where
72 T: PartialOrd,
73{
74 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
75 self.a.partial_cmp(&other.a)
76 }
77}
78
79impl<T> Ord for Line<T>
80where
81 T: Ord,
82{
83 fn cmp(&self, other: &Self) -> Ordering {
84 self.a.cmp(&other.a)
85 }
86}
87
88impl<T> Borrow<Slope<T>> for Line<T> {
89 fn borrow(&self) -> &Slope<T> {
90 &self.a
91 }
92}
93
94impl<T> Borrow<Query<T>> for Line<T> {
95 fn borrow(&self) -> &Query<T> {
96 &self.q
97 }
98}
99
100impl<T> Line<T> {
101 fn new(a: T, b: T, q: T) -> Self {
102 Self {
103 a: Slope(a),
104 b,
105 q: Query(q),
106 }
107 }
108}
109
110#[derive(Debug, Clone)]
111pub struct LineSet<T> {
112 map: BTreeSet<Line<T>>,
113}
114
115impl<T> Default for LineSet<T>
116where
117 T: Ord,
118{
119 fn default() -> Self {
120 Self {
121 map: Default::default(),
122 }
123 }
124}
125
126impl<T> LineSet<T>
127where
128 T: Copy + Bounded + Ord + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Div<Output = T>,
129{
130 pub fn new() -> Self {
131 Default::default()
132 }
133 pub fn insert(&mut self, a: T, b: T) {
134 fn f<T>(la: T, lb: T, ra: T, rb: T) -> T
135 where
136 T: Copy + Ord + Sub<Output = T> + Div<Output = T>,
137 {
138 debug_assert!(la > ra);
139 (rb - lb) / (la - ra)
140 }
141 let left = self.map.range(..Slope(a)).next_back().cloned();
142 let mut right = self.map.range(Slope(a)..).next().cloned();
143 match (&left, &right) {
144 (_, Some(r)) if a == r.a.0 => {
145 if r.b <= b {
146 return;
147 }
148 self.map.remove(r);
149 right = self.map.range(Slope(a)..).next().cloned();
150 }
151 (Some(l), Some(r)) if f(l.a.0, l.b, a, b) >= f(a, b, r.a.0, r.b) => return,
152 _ => {}
153 }
154 loop {
155 let rq = if let Some(r) = right {
156 let rq = f(a, b, r.a.0, r.b);
157 if rq >= r.q.0 {
158 self.map.remove(&r);
159 right = self.map.range(Slope(a)..).next().cloned();
160 continue;
161 }
162 rq
163 } else {
164 Bounded::maximum()
165 };
166 self.map.insert(Line::new(a, b, rq));
167 break;
168 }
169 if let Some(mut l) = left {
170 self.map.remove(&l);
171 let mut lq = f(l.a.0, l.b, a, b);
172 loop {
173 if let Some(ll) = self.map.range(..Slope(a)).next_back().cloned() {
174 self.map.remove(&ll);
175 let llq = f(ll.a.0, ll.b, l.a.0, l.b);
176 if llq >= lq {
177 l = ll;
178 lq = f(l.a.0, l.b, a, b);
179 continue;
180 } else {
181 self.map.insert(Line::new(ll.a.0, ll.b, llq));
182 }
183 };
184 break;
185 }
186 self.map.insert(Line::new(l.a.0, l.b, lq));
187 }
188 }
189 pub fn query_min(&self, x: T) -> Option<T> {
190 let Line { a, b, .. } = self.map.range(Query(x)..).next().cloned()?;
191 Some(a.0 * x + b)
192 }
193}