1use super::functions::*;
5
6#[allow(dead_code)]
10#[derive(Clone, Copy, Debug, PartialEq)]
11pub struct FloatInterval {
12 pub(super) lo: f64,
13 pub(super) hi: f64,
14}
15impl FloatInterval {
16 pub fn new(lo: f64, hi: f64) -> Self {
18 assert!(
19 lo <= hi,
20 "FloatInterval: lo ({}) must be <= hi ({})",
21 lo,
22 hi
23 );
24 Self { lo, hi }
25 }
26 pub fn try_new(lo: f64, hi: f64) -> Option<Self> {
28 if lo <= hi {
29 Some(Self { lo, hi })
30 } else {
31 None
32 }
33 }
34 pub fn lo(self) -> f64 {
36 self.lo
37 }
38 pub fn hi(self) -> f64 {
40 self.hi
41 }
42 pub fn width(self) -> f64 {
44 self.hi - self.lo
45 }
46 pub fn midpoint(self) -> f64 {
48 self.lo + (self.hi - self.lo) / 2.0
49 }
50 pub fn contains(self, x: f64) -> bool {
52 x >= self.lo && x <= self.hi
53 }
54 pub fn add(self, other: Self) -> Self {
56 Self::new(self.lo + other.lo, self.hi + other.hi)
57 }
58 pub fn sub(self, other: Self) -> Self {
60 Self::new(self.lo - other.hi, self.hi - other.lo)
61 }
62 pub fn mul(self, other: Self) -> Self {
64 let products = [
65 self.lo * other.lo,
66 self.lo * other.hi,
67 self.hi * other.lo,
68 self.hi * other.hi,
69 ];
70 let lo = products.iter().cloned().fold(f64::INFINITY, f64::min);
71 let hi = products.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
72 Self::new(lo, hi)
73 }
74 pub fn neg(self) -> Self {
76 Self::new(-self.hi, -self.lo)
77 }
78 pub fn intersect(self, other: Self) -> Option<Self> {
80 let lo = f64::max(self.lo, other.lo);
81 let hi = f64::min(self.hi, other.hi);
82 Self::try_new(lo, hi)
83 }
84 pub fn hull(self, other: Self) -> Self {
86 Self::new(f64::min(self.lo, other.lo), f64::max(self.hi, other.hi))
87 }
88 pub fn is_subset_of(self, other: Self) -> bool {
90 other.lo <= self.lo && self.hi <= other.hi
91 }
92 pub fn abs(self) -> Self {
94 if self.lo >= 0.0 {
95 self
96 } else if self.hi <= 0.0 {
97 self.neg()
98 } else {
99 Self::new(0.0, f64::max(-self.lo, self.hi))
100 }
101 }
102 pub fn square(self) -> Self {
104 self.mul(self)
105 }
106 pub fn mignitude(self) -> f64 {
108 if self.lo >= 0.0 {
109 self.lo
110 } else if self.hi <= 0.0 {
111 -self.hi
112 } else {
113 0.0
114 }
115 }
116 pub fn magnitude(self) -> f64 {
118 f64::max(self.lo.abs(), self.hi.abs())
119 }
120}
121#[allow(dead_code)]
123pub struct RangeMinSegTree {
124 n: usize,
125 data: Vec<i64>,
126}
127impl RangeMinSegTree {
128 const INF: i64 = i64::MAX;
130 pub fn build(values: &[i64]) -> Self {
132 let n = values.len();
133 let mut data = vec![Self::INF; 4 * (n + 1)];
134 if n > 0 {
135 Self::build_rec(&mut data, values, 1, 0, n - 1);
136 }
137 Self { n, data }
138 }
139 fn build_rec(data: &mut Vec<i64>, values: &[i64], node: usize, lo: usize, hi: usize) {
140 if lo == hi {
141 data[node] = values[lo];
142 return;
143 }
144 let mid = (lo + hi) / 2;
145 Self::build_rec(data, values, 2 * node, lo, mid);
146 Self::build_rec(data, values, 2 * node + 1, mid + 1, hi);
147 data[node] = data[2 * node].min(data[2 * node + 1]);
148 }
149 pub fn query_min(&self, l: usize, r: usize) -> Option<i64> {
151 if self.n == 0 || l > r || r >= self.n {
152 return None;
153 }
154 Some(self.query_rec(1, 0, self.n - 1, l, r))
155 }
156 fn query_rec(&self, node: usize, lo: usize, hi: usize, l: usize, r: usize) -> i64 {
157 if r < lo || hi < l {
158 return Self::INF;
159 }
160 if l <= lo && hi <= r {
161 return self.data[node];
162 }
163 let mid = (lo + hi) / 2;
164 let left = self.query_rec(2 * node, lo, mid, l, r);
165 let right = self.query_rec(2 * node + 1, mid + 1, hi, l, r);
166 left.min(right)
167 }
168 pub fn update(&mut self, i: usize, val: i64) {
170 if i < self.n {
171 self.update_rec(1, 0, self.n - 1, i, val);
172 }
173 }
174 fn update_rec(&mut self, node: usize, lo: usize, hi: usize, i: usize, val: i64) {
175 if lo == hi {
176 self.data[node] = val;
177 return;
178 }
179 let mid = (lo + hi) / 2;
180 if i <= mid {
181 self.update_rec(2 * node, lo, mid, i, val);
182 } else {
183 self.update_rec(2 * node + 1, mid + 1, hi, i, val);
184 }
185 self.data[node] = self.data[2 * node].min(self.data[2 * node + 1]);
186 }
187 pub fn len(&self) -> usize {
189 self.n
190 }
191 pub fn is_empty(&self) -> bool {
193 self.n == 0
194 }
195}
196#[allow(dead_code)]
201#[derive(Clone, Debug)]
202pub struct ValidatedInterval {
203 interval: FloatInterval,
204 certificate: String,
205 is_verified: bool,
206}
207impl ValidatedInterval {
208 pub fn verified(interval: FloatInterval, certificate: impl Into<String>) -> Self {
210 Self {
211 interval,
212 certificate: certificate.into(),
213 is_verified: true,
214 }
215 }
216 pub fn unverified(interval: FloatInterval) -> Self {
218 Self {
219 interval,
220 certificate: String::new(),
221 is_verified: false,
222 }
223 }
224 pub fn interval(&self) -> FloatInterval {
226 self.interval
227 }
228 pub fn is_verified(&self) -> bool {
230 self.is_verified
231 }
232 pub fn certificate(&self) -> &str {
234 &self.certificate
235 }
236 pub fn add(&self, other: &Self) -> Self {
239 Self {
240 interval: self.interval.add(other.interval),
241 certificate: format!("add({}, {})", self.certificate, other.certificate),
242 is_verified: self.is_verified && other.is_verified,
243 }
244 }
245 pub fn mul(&self, other: &Self) -> Self {
247 Self {
248 interval: self.interval.mul(other.interval),
249 certificate: format!("mul({}, {})", self.certificate, other.certificate),
250 is_verified: self.is_verified && other.is_verified,
251 }
252 }
253}
254#[allow(dead_code)]
256pub struct IntervalScheduler {
257 jobs: Vec<ScheduledJob>,
258}
259impl IntervalScheduler {
260 pub fn new(jobs: Vec<ScheduledJob>) -> Self {
262 Self { jobs }
263 }
264 fn latest_compatible(&self, idx: usize) -> Option<usize> {
266 let start = self.jobs[idx].start;
267 let mut result = None;
268 for i in 0..idx {
269 if self.jobs[i].finish <= start {
270 result = Some(i);
271 }
272 }
273 result
274 }
275 pub fn max_weight_schedule(&mut self) -> u64 {
277 self.jobs.sort_by_key(|j| j.finish);
278 let n = self.jobs.len();
279 if n == 0 {
280 return 0;
281 }
282 let mut dp = vec![0u64; n + 1];
283 for i in 0..n {
284 let weight = self.jobs[i].weight;
285 let p = self.latest_compatible(i).map(|j| j + 1).unwrap_or(0);
286 dp[i + 1] = dp[i].max(dp[p] + weight);
287 }
288 dp[n]
289 }
290 pub fn job_count(&self) -> usize {
292 self.jobs.len()
293 }
294}
295#[allow(dead_code)]
300pub struct KrawczykSolver {
301 max_iters: usize,
302 tolerance: f64,
303}
304impl KrawczykSolver {
305 pub fn new(max_iters: usize, tolerance: f64) -> Self {
307 Self {
308 max_iters,
309 tolerance,
310 }
311 }
312 pub fn solve<F, DF>(&self, mut x: FloatInterval, f: F, df: DF) -> Option<FloatInterval>
317 where
318 F: Fn(f64) -> f64,
319 DF: Fn(FloatInterval) -> FloatInterval,
320 {
321 for _ in 0..self.max_iters {
322 let m = x.midpoint();
323 let fm = f(m);
324 let dfx = df(x);
325 if dfx.mignitude() < 1e-15 {
326 return None;
327 }
328 let (lo, hi) = if dfx.lo > 0.0 {
329 (m - fm / dfx.lo, m - fm / dfx.hi)
330 } else if dfx.hi < 0.0 {
331 (m - fm / dfx.hi, m - fm / dfx.lo)
332 } else {
333 return None;
334 };
335 let k = FloatInterval::try_new(lo, hi)?;
336 let next = k.intersect(x)?;
337 if next.width() < self.tolerance {
338 return Some(next);
339 }
340 x = next;
341 }
342 None
343 }
344}
345#[allow(dead_code)]
347#[derive(Clone, Debug)]
348pub struct ScheduledJob {
349 pub id: usize,
351 pub start: u64,
353 pub finish: u64,
355 pub weight: u64,
357}
358impl ScheduledJob {
359 pub fn new(id: usize, start: u64, finish: u64, weight: u64) -> Self {
361 Self {
362 id,
363 start,
364 finish,
365 weight,
366 }
367 }
368 pub fn overlaps(&self, other: &Self) -> bool {
370 self.start < other.finish && other.start < self.finish
371 }
372 pub fn compatible(&self, other: &Self) -> bool {
374 !self.overlaps(other)
375 }
376}