DS 小结
-
Luogu P5046 [Ynoi2019 模拟赛] Yuno loves sqrt technology I
对于全局询问容易使用归并排序求解答案,因此考虑分块将这个复杂度进行优化。
将区间的贡献拆为散块对散块,散块对整块,整块对整块,分别处理计算。精细实现做到 \(\mathcal O(n\sqrt n)\)。
注意常数优化。
-
考虑分治,并且将二维问题拍成一维问题加上时间轴。
为什么可以这么处理?因为我们有可以处理历史最值的数据结构。因此可以猫树分治套上一个区间历史最值线段树求解。
时间复杂度 \(\mathcal O(n\log^2n)\)。
-
对于全局可以使用分治 \(\mathcal O(n^2)\) 求解。因此使用分块进行优化。
可以从左至右挨个计算每个块对答案的贡献,块和块之间独立。使用双指针可以做到 \(\mathcal O(n\sqrt n)\)。
超级卡常题。打死卡不过去了。
-
容易将函数表达成一个分段函数,即初始进这个区间的时候至少需要有 \(c_x\) 才能够在这个区间中被减去 \(x\) 次 \(p\)。容易发现这个东西可以放到线段树上,可以做到一次询问拆成 \(\mathcal O(\log n)\) 个区间,然后每个区间用二分做到一次询问 \(\mathcal O(\log^2 n)\) 的复杂度。
那么考虑如何预处理这个 \(c_x\),显然可以 \(c_{x+y}\gets\max(c_x,c_y-\text{sum}_{\text{lson}}+x\cdot p)\)。这样做是 \(\mathcal O(n^2)\) 的。发现可以使用决策单调性,然后即可把预处理优化至 \(\mathcal O(n\log n)\)。
总时间复杂度 \(\mathcal O(n\log n + q\log^2 n)\)。
-
将询问离线,按照 \(r\) 排序,从小到大加入矩形。
对于每一个点可以处理出一个 \(l_i\) 表示最晚被覆盖的时间,显然询问就是查询一个后缀和。
考虑这个 \(l_i\) 如何维护。容易发现,每次加入一个矩形就是对一个矩形内的关键点的区间覆盖,容易使用 KDT 做到单次修改 \(\mathcal O(\sqrt n)\) 的复杂度。
因为每次修改会影响后缀和,所以需要使用数据结构维护这个后缀和。由于总共有 \(\mathcal O(n\sqrt n)\) 次修改, \(\mathcal O(n)\) 次查询,因此使用 \(\mathcal O(1)-\mathcal O(\sqrt n)\) 的分块平衡复杂度。
总时间复杂度 \(\mathcal O(n\sqrt n)\)。
-
一个性质就是树上的一个连通块一定存在一个点,使得这个点在点分树上深度最小,且其他所有联通块中的点都在这个点的子树内。因此可以将所有询问扔给 \(x\) 的某个祖先进行处理。
然后对于子树内的贡献,一个点有效当且仅当这个点到当前分支中心的路径上的所有点都满足值域限制。因此在子树内做 2-side 即可。
时间复杂度 \(\mathcal O(n\log^2 n)\)。
-
首先所有连通块一定是一个连续的区间,这个容易证明。因此一个分割点 \(p\) 一定满足 \(\min\limits_{i=1}^p a_i>\max\limits_{i=p+1}^na_i\)。
考虑枚举后半部分的值 \(w\),将大于 \(w\) 的部分设为 \(1\),其余为 \(0\),那么这个 \(w\) 有贡献的序列形如 \(111\cdots1000\cdots0\)。考虑相邻两个数 \(a_i,a_{i+1}(a_i<a_{i+1})\),当 \(w\in [a_i,a_{i+1}]\) 会产生贡献。因此可以使用线段树去维护 \(w\) 值。对于每一对相邻的 \(a_i,a_{i+1}\),将 \([a_i,a_{i+1})\) 区间加 \(1\)。最后答案的数量即为 \(1\) 的个数。
将 \(a_0:=\infty,a_{n+1}:=0\),可以使得全局最小值为 \(1\),因此只需要维护最小值个数即可。
时间复杂度 \(\mathcal O(n\log n)\)。
-
离线询问,从右向左扫描线。设当前位置为 \(l\),开一个线段树维护 \([0,t]\) 时间的后缀 \(\min\) 和答案。
容易发现,每次修改就是对这个线段树上的一个后缀取 \(\min\)。而对于答案的统计就是这个点被修改的次数。
直接使用 Seg Beats 解决即可,时间复杂度 \(\mathcal O(n\log n)\)。