Skip to content

Commit 795e9ba

Browse files
committed
Add dynamic Li-Chao Tree
1 parent a76cab0 commit 795e9ba

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

files.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,13 @@
118118
{
119119
"title": "Wavelet Tree for K-th Order Statistics",
120120
"name": "mkthnum.cpp"
121+
},
122+
{
123+
"title": "Li-Chao Segment Tree",
124+
"name": "li_chao.cpp"
125+
},
126+
{
127+
"title": "Dynamic Li-Chao Segment Tree",
128+
"name": "li_chao_dynamic.cpp"
121129
}
122130
]

li_chao_dynamic.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// li_chao_dynamic.cpp
2+
// Eric K. Zhang; Jul. 3, 2018
3+
4+
#include <bits/stdc++.h>
5+
using namespace std;
6+
7+
typedef long long LL;
8+
9+
#define MAXLC 1000000000
10+
#define INF (1LL<<60)
11+
12+
inline LL f(LL m, LL b, int x) {
13+
return m * x + b;
14+
}
15+
16+
struct lc_node {
17+
LL m = 0, b = INF;
18+
lc_node *l = nullptr, *r = nullptr;
19+
20+
lc_node() {}
21+
lc_node(LL m, LL b) : m(m), b(b) {}
22+
~lc_node() { delete l; delete r; }
23+
24+
void add_line(LL nm, LL nb, int lo=0, int hi=MAXLC) {
25+
int mid = (lo + hi) / 2;
26+
bool bl = f(nm, nb, lo) < f(m, b, lo);
27+
bool bm = f(nm, nb, mid) < f(m, b, mid);
28+
if (bm) {
29+
swap(nm, m);
30+
swap(nb, b);
31+
}
32+
if (lo == hi || nb == INF)
33+
return;
34+
else if (bl != bm) {
35+
if (!l) l = new lc_node;
36+
l->add_line(nm, nb, lo, mid - 1);
37+
}
38+
else {
39+
if (!r) r = new lc_node;
40+
r->add_line(nm, nb, mid + 1, hi);
41+
}
42+
}
43+
44+
LL get(int x, int lo=0, int hi=MAXLC) {
45+
int mid = (lo + hi) / 2;
46+
LL ret = f(m, b, x);
47+
if (l && x < mid)
48+
ret = min(ret, l->get(x, lo, mid - 1));
49+
if (r && x > mid)
50+
ret = min(ret, r->get(x, mid + 1, hi));
51+
return ret;
52+
}
53+
54+
void clear() {
55+
delete l; delete r;
56+
m = 0, b = INF, l = nullptr, r = nullptr;
57+
}
58+
59+
} lc;
60+
61+
int main() {
62+
lc.add_line(2, -1); // y = 2x - 1
63+
lc.add_line(-1, 9); // y = 9 - x
64+
65+
cout << lc.get(0) << " = " << -1 << endl;
66+
cout << lc.get(1) << " = " << 1 << endl;
67+
cout << lc.get(3) << " = " << 5 << endl;
68+
cout << lc.get(4) << " = " << 5 << endl;
69+
cout << lc.get(5) << " = " << 4 << endl;
70+
cout << lc.get(100) << " = " << -91 << endl;
71+
}

0 commit comments

Comments
 (0)