leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit 8d7622906d0925ef8798f7160d928ae92ceed16e
parent 14ea57ff2a55311777dcca3221da99f556b13058
Author: Jack Sangdahl <jack@pngu.org>
Date:   Sat, 30 May 2026 09:30:34 -0600

3161. block placement queries

Diffstat:
Mblock_placement_queries.c | 169+++++++++++++++++++++++++++++++-------------------------------------------------
1 file changed, 65 insertions(+), 104 deletions(-)

diff --git a/block_placement_queries.c b/block_placement_queries.c @@ -17,137 +17,98 @@ */ struct segment_tree { + int n; int *tree; - int *max; - int size; }; -struct segment_tree *segment_tree_init(int size) { - struct segment_tree *obj = - (struct segment_tree *)malloc(sizeof(struct segment_tree)); - obj->size = size; - obj->tree = (int *)malloc(size * sizeof(int)); - obj->max = (int *)malloc(size * sizeof(int)); - for (int i = 0; i < size; i++) { - obj->tree[i] = -1; - obj->max[i] = -1; - } - return obj; -} - -void segment_tree_update(struct segment_tree *obj, int idx) { - int tmp = 0, max = 0, start = 0; - if (obj->tree[idx] != -1) { - start = idx; - max = obj->max[idx]; - } else { - for (int i = idx; i >= 0; i--) { - if (obj->tree[i] != -1) { - start = i; - max = obj->max[i]; - break; - } - } - } - obj->tree[idx] = -2; - for (int i = start; i < idx; i++) { - if (obj->tree[i] == -1) - obj->tree[i] = tmp; - if (tmp > max) - max = tmp; - tmp++; - if (obj->tree[i] == -2) - tmp = 1; - obj->max[i] = max; - } - if (tmp > max) - max = tmp; - obj->max[idx] = max; - for (int i = idx + 1; i < obj->size; i++) { - if (obj->tree[i] == -1) - break; - if (obj->max[i] == max && (obj->tree[i] == -2 || obj->tree[i] == max)) - break; - if (obj->tree[i] == -2) { - if (tmp > max) - max = tmp; - tmp = 0; - - } else - obj->tree[i] = tmp; - if (tmp > max) - max = tmp; - tmp++; - obj->max[i] = max; - } +void update(struct segment_tree *obj, int i, int val) { + for (obj->tree[i += obj->n] = val; i > 1; i >>= 1) + obj->tree[i >> 1] = fmax(obj->tree[i], obj->tree[i ^ 1]); } -int segment_tree_query(struct segment_tree *obj, int end, int size) { - if (end - size < 0) - return 0; - for (int i = end; i >= 0; i--) { - if (end - i >= size) - return size; - if (obj->tree[i] != -1) - return obj->max[i]; +int query(struct segment_tree *obj, int r) { + int res = 0; + for (int l = obj->n, r_idx = r + obj->n + 1; l < r_idx; + l >>= 1, r_idx >>= 1) { + if (l & 1) + res = fmax(res, obj->tree[l++]); + if (r_idx & 1) + res = fmax(res, obj->tree[--r_idx]); } - return 0; -} - -bool is_intersected(struct segment_tree *obj, int end, int size) { - if (end - size < 0) - return false; - int max = segment_tree_query(obj, end, size); - return max >= size; + return res; } bool *getResults(int **queries, int queriesSize, int *queriesColSize, int *returnSize) { + int max_x = 0, n = 1; + for (int i = 0; i < queriesSize; i++) + max_x = fmax(max_x, queries[i][1]); + while (n <= max_x + 1) + n *= 2; + struct segment_tree st = {n, (int *)calloc(2 * n, sizeof(int))}; + int *obstacles = (int *)malloc((queriesSize + 1) * sizeof(int)); + obstacles[0] = 0; + int obstacle_cnt = 1; + bool *ans = (bool *)malloc(queriesSize * sizeof(bool)); *returnSize = 0; - int tree_size = 0; - for (int i = 0; i < queriesSize; i++) { - if (tree_size < queries[i][1]) - tree_size = queries[i][1]; - if (queriesColSize[i] == 3 && queries[i][0] == 2) - (*returnSize)++; - } - tree_size++; - bool *ans = (bool *)malloc(*returnSize * sizeof(bool)); - struct segment_tree *tree = segment_tree_init(tree_size); - int idx = 0; for (int i = 0; i < queriesSize; i++) { - int m = queriesColSize[i], *curr = queries[i]; - if (m == 2 && curr[0] == 1) { - int val = curr[1]; - segment_tree_update(tree, val); - } else if (m == 3 && curr[0] == 2) { - int end = curr[1], size = curr[2]; - ans[idx++] = is_intersected(tree, end, size); + int type = queries[i][0], x = queries[i][1]; + int left = 0, right = obstacle_cnt; + while (left < right) { + int mid = left + (right - left) / 2; + if (obstacles[mid] > x) + right = mid; + else + left = mid + 1; + } + int idx = left; + if (type == 1) { + int prev = obstacles[idx - 1]; + int next = idx < obstacle_cnt ? obstacles[idx] : -1; + update(&st, x, x - prev); + if (next != -1) + update(&st, next, next - x); + memmove(&obstacles[idx + 1], &obstacles[idx], + (obstacle_cnt - idx) * sizeof(int)); + obstacles[idx] = x; + obstacle_cnt++; + } else { + int sz = queries[i][2], prev = obstacles[idx - 1]; + int max = fmax(x - prev, query(&st, prev)); + ans[(*returnSize)++] = (sz <= max); } } - free(tree->tree), free(tree); + free(obstacles); + free(st.tree); return ans; } int main() { - int q1i[4][3] = {{1, 2}, {2, 3, 3}, {2, 3, 1}, {2, 2, 2}}, qcs1[] = {}, rs1; - int q2i[5][3] = {{1, 7}, {2, 7, 6}, {1, 2}, {2, 7, 5}, {2, 7, 6}}, - qcs2[] = {}, rs2; + int q1i[4][3] = {{1, 2}, {2, 3, 3}, {2, 3, 1}, {2, 2, 2}}; + int qcs1[] = {}, rs1; + bool r1[] = {false, true, true}; + int q2i[5][3] = {{1, 7}, {2, 7, 6}, {1, 2}, {2, 7, 5}, {2, 7, 6}}; + int qcs2[] = {}, rs2; + bool r2[] = {true, true, false}; for (int i = 0; i < ARRAY_SIZE(q1i); i++) qcs1[i] = ARRAY_SIZE(q1i[i]); for (int i = 0; i < ARRAY_SIZE(q2i); i++) qcs2[i] = ARRAY_SIZE(q2i[i]); struct two_d_arr *q1 = - two_d_arr_init(ARRAY_SIZE(q1i), ARRAY_SIZE(q1i[0]), q1i); + two_d_arr_init(ARRAY_SIZE(q1i), ARRAY_SIZE(q1i[1]), q1i); struct two_d_arr *q2 = - two_d_arr_init(ARRAY_SIZE(q2i), ARRAY_SIZE(q2i[0]), q2i); + two_d_arr_init(ARRAY_SIZE(q2i), ARRAY_SIZE(q2i[1]), q2i); bool *gr1 = getResults(q1->arr, q1->row_size, qcs1, &rs1); bool *gr2 = getResults(q2->arr, q2->row_size, qcs2, &rs2); - for (int i = 0; i < rs1; i++) - printf("%d ", gr1[i]); // expect: 0 1 1 + for (int i = 0; i < rs1; i++) { + printf("%d ", gr1[i]); + assert(gr1[i] == r1[i]); + } printf("\n"); - for (int i = 0; i < rs2; i++) - printf("%d ", gr1[i]); // expect: 1 1 1 + for (int i = 0; i < rs2; i++) { + printf("%d ", gr2[i]); + assert(gr2[i] == r2[i]); + } printf("\n"); free(gr1); free(gr2);