// 目标值定义, 此例为最大值 intchoose(int a, int b){ returnmax(a, b); }
// 查询[a, b]之间的目标值,如果要求前缀最大值,那么用logn的写法即可 intquery(int a, int b){ int ret = nums[b]; while (b >= a) { ret = choose(ret, nums[b]); b--; for (; b - lowbit(b) >= a; b -= lowbit(b)) { // 如果是b - lowbit(b) + 1 >= a,在a==1时会出问题 ret = choose(ret, tree[b]); } } return ret; }
// 修改下标为idx的数为val voidupdate(int idx, int val){ nums[idx] = val; tree[idx] = val; while (idx <= n) { int lx = lowbit(idx); // 假设现在树状数组维护的是区间最大值。在单点修改时,如果把nums[8]改小了,那么如果tree[8]保存的最大值正好就是nums[8],那么tree[8]要由tree[7], tree[6], tree[4]中的某个数取代 for (int i = 1; i < lx; i <<= 1) { tree[idx] = choose(tree[idx], tree[idx - i]); } idx += lx; } } };
intlengthOfLIS(vector<int>& nums, int k){ int N = 1e5 + 10; bit tr(N); int cnt = 0; for (auto i: nums) { if (i == 1) { tr.update(1, 1); } else { int ma = tr.query(max(1, i - k), i-1); tr.update(i, ma + 1); } } return tr.query(1, N); } };