Skip to content

Commit 0b8f446

Browse files
author
liaomingtian
committed
✨ feat(LiChaoTreeDynamicPersistent):
1 parent 061a41a commit 0b8f446

10 files changed

+1759
-33
lines changed

10_分治法/李超线段树/LiChaoDynamic.go

Whitespace-only changes.

10_分治法/李超线段树/LiChao.go renamed to 10_分治法/李超线段树/LiChaoTree.go

+15-14
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,13 @@ type queryPair = struct {
128128
}
129129

130130
type LiChaoTree struct {
131-
n, offset int
132-
lower, higher int
133-
compress bool
134-
minimize bool
135-
xs []int
136-
lines []Line
137-
lineIds []int
131+
n, offset int
132+
start, end int
133+
compress bool
134+
minimize bool
135+
xs []int
136+
lines []Line
137+
lineIds []int
138138
}
139139

140140
// 指定查询的 x 值建立李超线段树,采用坐标压缩.
@@ -167,9 +167,10 @@ func NewLiChaoTreeCompress(queryX []int, minimize bool) *LiChaoTree {
167167
}
168168

169169
// 指定查询的 x 值范围建立李超线段树,不采用坐标压缩.
170-
// higher - lower <= 1e6.
171-
func NewLiChaoTreeNoCompress(lower, higher int, minimize bool) *LiChaoTree {
172-
n := higher - lower
170+
// end - start <= 1e6.
171+
func NewLiChaoTreeNoCompress(start, end int, minimize bool) *LiChaoTree {
172+
end++
173+
n := end - start
173174
log := 1
174175
for (1 << log) < n {
175176
log++
@@ -181,7 +182,7 @@ func NewLiChaoTreeNoCompress(lower, higher int, minimize bool) *LiChaoTree {
181182
}
182183
return &LiChaoTree{
183184
n: n, offset: offset,
184-
lower: lower, higher: higher,
185+
start: start, end: end,
185186
compress: false, minimize: minimize,
186187
lineIds: lineIds,
187188
}
@@ -315,7 +316,7 @@ func (tree *LiChaoTree) _evaluateInner(fid int, x int) T {
315316
if tree.compress {
316317
target = tree.xs[min(x, tree.n-1)]
317318
} else {
318-
target = x + tree.lower
319+
target = x + tree.start
319320
}
320321
return Evaluate(tree.lines[fid], target)
321322
}
@@ -324,10 +325,10 @@ func (tree *LiChaoTree) _getIndex(x int) int {
324325
if tree.compress {
325326
return sort.SearchInts(tree.xs, x)
326327
}
327-
if x < tree.lower || x > tree.higher {
328+
if x < tree.start || x > tree.end {
328329
panic("x out of range")
329330
}
330-
return x - tree.lower
331+
return x - tree.start
331332
}
332333

333334
func min(a, b int) int {

10_分治法/李超线段树/LiChao.ts renamed to 10_分治法/李超线段树/LiChaoTree.ts

+14-13
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ const INF = 2e9 // 2e15
1111
class LiChaoTree {
1212
private readonly _n: number
1313
private readonly _offset: number
14-
private readonly _lower: number
15-
private readonly _higher: number
14+
private readonly _start: number
15+
private readonly _end: number
1616
private readonly _compress: boolean
1717
private readonly _minimize: boolean
1818
private readonly _lineIds: Int32Array
@@ -33,11 +33,11 @@ class LiChaoTree {
3333

3434
/**
3535
* 指定查询的 x 值范围建立李超线段树,不采用坐标压缩.
36-
* higher - lower <= 1e6.
36+
* end - start <= 1e6.
3737
*/
3838
constructor(
39-
lower: number,
40-
higher: number,
39+
start: number,
40+
end: number,
4141
options?: {
4242
minimize?: boolean
4343
evaluate?: (line: Line, x: number) => number
@@ -56,8 +56,8 @@ class LiChaoTree {
5656
const lineIds = new Int32Array(offset << 1).fill(-1)
5757
this._n = n
5858
this._offset = offset
59-
this._lower = 0
60-
this._higher = 0
59+
this._start = 0
60+
this._end = 0
6161
this._compress = true
6262
this._minimize = minimize
6363
this._lineIds = lineIds
@@ -66,15 +66,16 @@ class LiChaoTree {
6666
this._evaluate = evaluate
6767
} else {
6868
const { minimize = true, evaluate = (line: Line, x: number) => line.k * x + line.b } = arg3 || {}
69+
arg2++
6970
const n = arg2 - arg1
7071
let log = 1
7172
while (1 << log < n) log++
7273
const offset = 1 << log
7374
const lineIds = new Int32Array(offset << 1).fill(-1)
7475
this._n = n
7576
this._offset = offset
76-
this._lower = arg1
77-
this._higher = arg2
77+
this._start = arg1
78+
this._end = arg2
7879
this._compress = false
7980
this._minimize = minimize
8081
this._lineIds = lineIds
@@ -172,14 +173,14 @@ class LiChaoTree {
172173

173174
private _evaluateInner(fid: number, x: number): number {
174175
if (fid === -1) return this._minimize ? INF : -INF
175-
const target = this._compress ? this._xs[Math.min(x, this._n - 1)] : x + this._lower
176+
const target = this._compress ? this._xs[Math.min(x, this._n - 1)] : x + this._start
176177
return this._evaluate(this._lines[fid], target)
177178
}
178179

179180
private _getIndex(x: number): number {
180181
if (this._compress) return LiChaoTree._lowerBound(this._xs, x)
181-
if (x < this._lower || x > this._higher) throw new RangeError(`x out of range: ${x}`)
182-
return x - this._lower
182+
if (x < this._start || x > this._end) throw new RangeError(`x out of range: ${x}`)
183+
return x - this._start
183184
}
184185

185186
private static _lowerBound(arr: ArrayLike<number>, x: number): number {
@@ -239,7 +240,7 @@ if (require.main === module) {
239240
const points = Array(q)
240241
.fill(0)
241242
.map(() => Math.floor(-Math.random() * 1e5) + 5e4)
242-
const tree1 = new LiChaoTree(points, { minimize: false })
243+
const tree1 = new LiChaoTree(-1e5, 1e5, { minimize: false })
243244
const tree2 = new Mocker(false)
244245
for (let i = 0; i < q; i++) {
245246
const k = -Math.floor(Math.random() * 1e5) + 5e4

0 commit comments

Comments
 (0)