【线段树】个人练习-Leetcode-3161. Block Placement Queries

题目链接:https://leetcode.cn/problems/block-placement-queries/description/

题目大意:在x轴上,有两种操作:

  • 在某个点上插入一个障碍物
  • 查询,在[0, x]区间内,能否放下长度为sz的物品

插入和查询操作交替进行,返回每次查询的结果。

思路:一开始时看见题目写的"anywhere"以为是【区间内每处都能放下物品】,寻思着那不是整个区间都没有障碍物才行吗,好像判断有点简单了。后来才发现只要有一处能放下就行了。

那其实就是查询[0, x]区间内,被障碍物隔开的各个区间中,能存储的最大长度。这种涉及区间查询的,应该用线段树来解决。然而长久不写已经忘了线段树怎么写了...看了很多题解,还是灵神的比较清晰。

更新i处的值为val

cpp 复制代码
	void update(int o, int l, int r, int i, int val) {
        if (l == r) {
            tree[o] = val;
            return;
        }
        int mid = (l + r) / 2;
        if (i <= mid)
            update(o * 2, l, mid, i, val);
        else
            update(o * 2 + 1, mid+1, r, i, val);
        tree[o] = max(tree[o * 2], tree[o*2 + 1]);
    }

返回[0, x]中最大的区间长度

cpp 复制代码
	int query(int o, int l, int r, int x) {
        if (r <= x)
            return tree[o];
        int mid = (l + r) / 2;
        if (x <= mid) 
            return query(o * 2, l, mid, x);
        return max(tree[o * 2], query(o * 2 + 1, mid + 1, r, x)); 
    }

对于[0, x]来说,要么最大长度在[0, pre]prex左边的最大的障碍物位置)之间,要么在[pre, x]之间(因为每个query中x其实也相当于一个暂时的障碍)。

完整代码

cpp 复制代码
class Solution {
public:
    vector<int> tree;

    void update(int o, int l, int r, int i, int val) {
        if (l == r) {
            tree[o] = val;
            return;
        }
        int mid = (l + r) / 2;
        if (i <= mid)
            update(o * 2, l, mid, i, val);
        else
            update(o * 2 + 1, mid+1, r, i, val);
        tree[o] = max(tree[o * 2], tree[o*2 + 1]);
    }


    int query(int o, int l, int r, int x) {
        if (r <= x)
            return tree[o];
        int mid = (l + r) / 2;
        if (x <= mid) 
            return query(o * 2, l, mid, x);
        return max(tree[o * 2], query(o * 2 + 1, mid + 1, r, x)); 
    }


    vector<bool> getResults(vector<vector<int>>& queries) {
        int maxn = 0;
        for (auto q : queries)
            maxn = max(maxn, q[1]);
        maxn++;
        
        set<int> st{0, maxn};
        tree.resize(2 << (32 - __builtin_clz(maxn)));
        vector<bool> res;
        
        for (auto q : queries) {
            int x = q[1];
            auto it = st.lower_bound(x);
            int pre = *std::prev(it);
            if (q[0] == 1) {
                int nxt = *it;
                st.insert(x);
                update(1, 0, maxn, x, x - pre);
                update(1, 0, maxn, nxt, nxt - x);
            }
            else {
                int maxlen = max(query(1, 0, maxn, pre), x - pre);
                res.push_back(maxlen >= q[2]);
            }
        }
        return res;
    }
};
相关推荐
Pluchon8 小时前
硅基计划4.0 简单模拟实现AVL树&红黑树
java·数据结构·算法
生锈的键盘8 小时前
推荐算法实践:交叉特征的理解
算法
乌萨奇也要立志学C++8 小时前
【洛谷】BFS 求解最短路:从马的遍历到迷宫问题的实战解析
算法·宽度优先
老鼠只爱大米8 小时前
LeetCode经典算法面试题 #46:全排列(回溯、交换、剪枝等五种实现方案详细解析)
算法·leetcode·剪枝·回溯·全排列·stj算法
Dovis(誓平步青云)9 小时前
《滑动窗口算法:从 “暴力遍历” 到 “线性高效” 的思维跃迁》
运维·服务器·数据库·算法
_OP_CHEN9 小时前
【算法基础篇】(五十七)线性代数之矩阵乘法从入门到实战:手撕模板 + 真题详解
线性代数·算法·矩阵·蓝桥杯·c/c++·矩阵乘法·acm/icpc
天天爱吃肉82189 小时前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车
im_AMBER9 小时前
Leetcode 114 链表中的下一个更大节点 | 删除排序链表中的重复元素 II
算法·leetcode
xhbaitxl9 小时前
算法学习day38-动态规划
学习·算法·动态规划
多恩Stone9 小时前
【3D AICG 系列-6】OmniPart 训练流程梳理
人工智能·pytorch·算法·3d·aigc