6066. 统计区间中的整数数目(区间并集模板、动态开点)

简介: 笔记

题意


10.png


样例


11.png



数据范围


12.png


代码


  • 动态开点
class CountIntervals {
    CountIntervals *left = nullptr, *right = nullptr;
    int l, r, sum = 0;
public:
    CountIntervals() :l(1), r(1e9) {}
    CountIntervals(int l, int r) :l(l), r(r) {}
    void add(int L, int R) {
        if(sum >= r - l + 1) return ; // 到该已经覆盖完的节点,不用向下走了
        if(l >= L && r <= R) { sum = r - l + 1; return ; } // 该节点能被完全覆盖
        int mid = (l + r) >> 1;
        if(left == nullptr) left = new CountIntervals(l, mid);
        if(right == nullptr) right = new CountIntervals(mid + 1, r);
        if(L <= mid) left->add(L, R);
        if(R > mid) right->add(L, R);
        sum = left->sum + right->sum;
    }
    int count() { return sum; }
};
/**
 * Your CountIntervals object will be instantiated and called as such:
 * CountIntervals* obj = new CountIntervals();
 * obj->add(left,right);
 * int param_2 = obj->count();
 */
  • set集合,二分
class CountIntervals {
public:
    #define PII pair<int, int>
    set<PII> s; // <R, L>,存的是R,L
    int res = 0;
    CountIntervals() {}
    // 以右端点排
    void add(int left, int right) {
        int l = left, r = right;
        // 找到第一个右端点>l, 即从相交的开始。
        auto it = s.lower_bound(PII{l, -1e9});
        // 向后找到第一个左端点>r,即不在相交了
        while(it != s.end()) {
            if(it->second > r) break;
            // 维护最终合并完的最小l,最大r
            l = min(it->second, l);
            r = max(it->first, r);
            // 减去所有找到的区间值
            res -= it->first - it->second + 1;
            s.erase(it++);
        }
        // 加上最终合并的区间值
        res += r - l + 1;
        // 在插入当前合并的区间
        s.insert(PII{r, l});
    }
    int count() { return res; }
};
/**
 * Your CountIntervals object will be instantiated and called as such:
 * CountIntervals* obj = new CountIntervals();
 * obj->add(left,right);
 * int param_2 = obj->count();
 */
相关文章
|
6月前
|
算法 测试技术 C#
C++二分查找算法:包含每个查询的最小区间
C++二分查找算法:包含每个查询的最小区间
|
5月前
39.组合总和(回溯)
39.组合总和(回溯)
|
人工智能 BI 索引
【Leetcode -598.范围求和Ⅱ -599.两个列表的最小索引总和】
【Leetcode -598.范围求和Ⅱ -599.两个列表的最小索引总和】
44 0
|
6月前
|
算法 测试技术 C#
【并集查找 最大公约数 调和数】952. 按公因数计算最大组件大小
【并集查找 最大公约数 调和数】952. 按公因数计算最大组件大小
|
6月前
|
算法 测试技术 C#
【线段树】2276. 统计区间中的整数数目
【线段树】2276. 统计区间中的整数数目
|
6月前
|
算法 测试技术 C#
【线段树 区间位运算模板】3117划分数组得到最小的值之和
【线段树 区间位运算模板】3117划分数组得到最小的值之和
|
6月前
|
Java 测试技术
统计满足条件的子集个数
统计满足条件的子集个数
43 0
|
6月前
【每日一题Day269】LC1851包含每个查询的最小区间 | 排序+离线查询+小顶堆
【每日一题Day269】LC1851包含每个查询的最小区间 | 排序+离线查询+小顶堆
41 0
|
Python
将列表按照指定的规则排序并添加平均值
将列表按照指定的规则排序并添加平均值
68 1
LeetCode-2044 统计按位或能得到最大值子集的数目
LeetCode-2044 统计按位或能得到最大值子集的数目