defmodify(o: int, l: int, r: int, i: int, val: int) -> None: if l == r: mx[o] = val return m = (l + r) // 2 if i <= m: modify(o * 2, l, m, i, val) else: modify(o * 2 + 1, m + 1, r, i, val) mx[o] = max(mx[o * 2], mx[o * 2 + 1])
# 返回区间 [L,R] 内的最大值 defquery(o: int, l: int, r: int, L: int, R: int) -> int: # L 和 R 在整个递归过程中均不变,将其大写,视作常量 if L <= l and r <= R: return mx[o] res = 0 m = (l + r) // 2 if L <= m: res = query(o * 2, l, m, L, R) if R > m: res = max(res, query(o * 2 + 1, m + 1, r, L, R)) return res
for x in nums: if x == 1: modify(1, 1, u, 1, 1) else: res = 1 + query(1, 1, u, max(x - k, 1), x - 1) modify(1, 1, u, x, res) return mx[1]
publicintlengthOfLIS(int[] nums, int k) { varu=0; for (var x : nums) u = Math.max(u, x); max = newint[u * 4]; for (var x : nums) { if (x == 1) modify(1, 1, u, 1, 1); else { varres=1 + query(1, 1, u, Math.max(x - k, 1), x - 1); modify(1, 1, u, x, res); } } return max[1]; }
privatevoidmodify(int o, int l, int r, int idx, int val) { if (l == r) { max[o] = val; return; } varm= (l + r) / 2; if (idx <= m) modify(o * 2, l, m, idx, val); else modify(o * 2 + 1, m + 1, r, idx, val); max[o] = Math.max(max[o * 2], max[o * 2 + 1]); }
// 返回区间 [L,R] 内的最大值 privateintquery(int o, int l, int r, int L, int R) { // L 和 R 在整个递归过程中均不变,将其大写,视作常量 if (L <= l && r <= R) return max[o]; varres=0; varm= (l + r) / 2; if (L <= m) res = query(o * 2, l, m, L, R); if (R > m) res = Math.max(res, query(o * 2 + 1, m + 1, r, L, R)); return res; } }
voidmodify(int o, int l, int r, int i, int val){ if (l == r) { max[o] = val; return; } int m = (l + r) / 2; if (i <= m) modify(o * 2, l, m, i, val); elsemodify(o * 2 + 1, m + 1, r, i, val); max[o] = std::max(max[o * 2], max[o * 2 + 1]); }
// 返回区间 [L,R] 内的最大值 intquery(int o, int l, int r, int L, int R){ // L 和 R 在整个递归过程中均不变,将其大写,视作常量 if (L <= l && r <= R) return max[o]; int res = 0; int m = (l + r) / 2; if (L <= m) res = query(o * 2, l, m, L, R); if (R > m) res = std::max(res, query(o * 2 + 1, m + 1, r, L, R)); return res; }
public: intlengthOfLIS(vector<int> &nums, int k){ int u = *max_element(nums.begin(), nums.end()); max.resize(u * 4); for (int x: nums) { if (x == 1) modify(1, 1, u, 1, 1); else { int res = 1 + query(1, 1, u, std::max(x - k, 1), x - 1); modify(1, 1, u, x, res); } } return max[1]; } };
func(t seg) build(o, l, r int) { t[o].l, t[o].r = l, r if l == r { return } m := (l + r) >> 1 t.build(o<<1, l, m) t.build(o<<1|1, m+1, r) }
func(t seg) modify(o, i, val int) { if t[o].l == t[o].r { t[o].max = val return } m := (t[o].l + t[o].r) >> 1 if i <= m { t.modify(o<<1, i, val) } else { t.modify(o<<1|1, i, val) } t[o].max = max(t[o<<1].max, t[o<<1|1].max) }
// 返回区间 [l,r] 内的最大值 func(t seg) query(o, l, r int) int { if l <= t[o].l && t[o].r <= r { return t[o].max } m := (t[o].l + t[o].r) >> 1 if r <= m { return t.query(o<<1, l, r) } if m < l { return t.query(o<<1|1, l, r) } return max(t.query(o<<1, l, r), t.query(o<<1|1, l, r)) }
funclengthOfLIS(nums []int, k int)int { mx := 0 for _, x := range nums { mx = max(mx, x) } t := make(seg, mx*4) t.build(1, 1, mx) for _, x := range nums { if x == 1 { t.modify(1, 1, 1) } else { t.modify(1, x, 1+t.query(1, max(x-k, 1), x-1)) } } return t[1].max }
funcmax(a, b int)int { if b > a { return b } return a }
复杂度分析
时间复杂度:O(n\log U),其中 n 为 nums 的长度,U=\max(\textit{nums})。