CF1034D Intervals of Intervals
Posted kyEEcccccc@cnblogs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1034D Intervals of Intervals相关的知识,希望对你有一定的参考价值。
简要题意
给定 \\(n\\) 个区间组成的序列,定义它的一个连续段的价值为这个段内所有区间的并覆盖的长度。求价值前 \\(k\\) 大的段的价值和。
数据范围:\\(1\\le n\\le 3\\times 10^5, 1\\le k\\le \\min\\\\fracn(n-1)2, 10^9\\\\)。
题解
考虑一个经典问题,\\(q\\) 次询问求某个连续段的价值。考虑离线,动态维护对于当前右端点,每个左端点的答案。考虑一个位置最后一次被覆盖是在第 \\(t\\) 个区间,那么对于所有 \\(1\\le l\\le t\\) 这个位置都会贡献 \\(1\\)。那么考虑将右端点右移一位时如何维护。显然类似珂朵莉树,可以证明修改段的次数是均摊 \\(\\mathrm O(n)\\)。那么直接考虑用线段树,修改段等价于一次区间加。总时间复杂度 \\(\\mathrm O(n\\log n)\\)。把线段树换成主席树,可以做到在线询问。
接着考虑这题,容易想到先找到排名为 \\(k\\) 的连续段的价值,就很好做了,那么二分答案,转化为计数价值大于 \\(X\\) 的连续段。考虑一个结论:\\(V(L_i, R_i + 1)\\ge V(L_i, R_i) \\ge V(L_i + 1, R_i)\\)。则存在 \\(pos(r, X)\\) 为最大的 \\(l\\) 使得 \\(V(l, r) > X\\)。同时容易得出,\\(V(r, X)\\) 关于 \\(r\\) 单增。通过一个指针维护,把珂朵莉树放在二分外面,预处理出每个 \\(r\\) 增加的区间,用前缀和维护即可,时间复杂度 \\(\\mathrm O(n\\log n)\\)。
data-stream-as-disjoint-intervals
https://leetcode.com/problems/data-stream-as-disjoint-intervals/
/** * Definition for an interval. * struct Interval { * int start; * int end; * Interval() : start(0), end(0) {} * Interval(int s, int e) : start(s), end(e) {} * }; */ class SummaryRanges { vector<Interval> vec; int find(int val) { int vlen = vec.size(); if (vlen == 0) { return -1; } int begin = 0; int end = vlen - 1; int mid; while (begin <= end) { mid = begin + (end - begin) / 2; // Here <= vs. > if (vec[mid].start > val) { end = mid - 1; } else { begin = mid + 1; } } // Here it‘s important to return end return end; } public: /** Initialize your data structure here. */ SummaryRanges() { } void addNum(int val) { int idx = find(val); if (idx < 0) { if (vec.size() > 0 && vec[0].start == val+1) { vec[0].start = val; } else { Interval inter(val, val); vec.insert(vec.begin(), inter); } } else { if (vec[idx].end == val-1) { vec[idx].end = val; } else if (vec[idx].end < val-1) { Interval inter(val, val); vec.insert(vec.begin()+idx+1, inter); idx++; } // check latter if (vec.size() > idx+1 && vec[idx+1].start == vec[idx].end + 1) { vec[idx].end = vec[idx+1].end; vec.erase(vec.begin()+idx+1); } } } vector<Interval> getIntervals() { return vec; } }; /** * Your SummaryRanges object will be instantiated and called as such: * SummaryRanges obj = new SummaryRanges(); * obj.addNum(val); * vector<Interval> param_2 = obj.getIntervals(); */
以上是关于CF1034D Intervals of Intervals的主要内容,如果未能解决你的问题,请参考以下文章
data-stream-as-disjoint-intervals