1-BJ-数据结构
lxl:长度 >= k 大家还不熟悉吗,让我们打开洛谷,NOIP2024,NOIP2025
来看这个粉兔题。
什么!
\(r'\) 更简单,咦,不是,让我看下题。
这翻译神金吧,夹带私货。
你看 NOIPT4 nqlog 都过了,所以有信仰就行。
\(25*10^4\) 是什么小众变态写法?
还有梦幻联动。
(12.23 I
不是,你们没做过追忆?
这是追忆环节。
追忆这个 idea 烂大街了。原题一大片。
这个比追忆难多了。
12.22 log 数据结构
区间的区间并:每次右移右端点要把 \(lst[l\dots r]\) 改成 r+1。
这东西可以颜色段均摊,查询部分可以树状数组。
A.TEST_73
每次只保留编号在区间 [l,r] 内的边和点,求连通块个数。
最后留下来的一定是树上的连通子图,相当于森林,森林连通块数是点-边。
点:全部保留,r-l+1
边:a-c->b \(l\le a,b,c\le r\),三维数点。
因为 \(l,r\) 不变,所以取最小和最大值,就是二位数点 \(O(n\log n)\)
B.Closest Equals
原。
C.
给定 n 个相互不包含的区间 \([l',r']\),每个区间有权值,给定 \(l,r,k\),求在 \([l,r]\) 范围内长度 \(\ge k\) 的区间最大值。
考虑两两不包含的这个性质,进行编号后可以发现肯定是按顺序的,所以询问也是一段区间。
然后就是 k和编号两维限制,扫描线。
但是 lxl 看错题了,没看到不互相包含,求和,于是:
画在图上,没有长度限制相当于紧贴 y=x 的一个三角形内的信息,加上 k 的限制可以通过右移这条线完成。
然后差分一下,假设所求点为 \((a,b)\),若 \((x,y)\) 在三角形内 \(y\le a,x+y\le a+b\)
D.
平面上有n个矩形,给你一个常数d,你需要找到一个点(x,y),满足对任意整数k1,k2,(x+k1d,y+k2d)都不在任何矩形中。
可以分成若干 d*d 的矩形,有一个矩形包含了整个网格,直接无解。
然后可以把这些矩形直接平移到第一个格子,对于列或行超过 2 个格子的部分,只用移动中间的一块就可以了。
E.[Ynoi2004] rsxc
弱化版。
给定 n 个不相互包含的区间 \([l',r']\) 求 \([l,r]\) 与所有 \(l\le r' \le r\) 的区间的交集之和。
这东西前缀和一下,分成两部分。完全包含和不完全包含,分界点预处理一下,就线性了。
F.[Ynoi Easy Round 2023] TEST_107
究极卡常题。
相当于不包含一个数的最长区间长度,就是 B 了。
但是如果是 1 2 3 4 5 就不对了,所以还有找区间中所有出现过的数的最靠左的位置中最靠右的。
听起来很神经病,但是其实简单扫描线就可以了,每次把这些值的最左边的值扔进 set,可以简单处理。
右边其实同理,也能用线段树做,一坨……
G.k-d-sequence
按 \(\bmod d\) 分组,只有一样的部分可能有答案。
考虑什么情况下可能有结果,首先不能有相同值,其次就是空隙数量不超过 k。
空隙数量就是 \(max-min+1-(r-l+1)\),就是满足 \(max-min-r+l-k\le 0\)
扫描 r,然后在 l 记录这个东西,然后右移指针,用单调栈维护一下,区间修改。
查找可以线段树二分。
H.フードコート
交换时间和位置,维护一下修改情况。
麻烦的点在于有可能会删空,在不空的情况下可以独立考虑加入删除。
假设删了 x 个,直接查第 x+k 个位置,线段树二分。
可以找最后删空的位置,考虑什么时候会删空,就是前缀和最小的位置。
证明一下,因为删空必然有一段为负,而每次删空必然前缀和增加一个负数,最后一次必然前面有最多的删空次数。
且此时如果有值,那么它一定会多一个正贡献,所以前面一定有比它更小的。
I.
给一些路径,求区间路径并。
同区间的区间并,套个树剖就行了。
J.众数
分块,每次从最后的块开始,从后往前找,从前往后扫这个块。
可以倍增分块,因为每次浪费的查询长度一定不会长于 k。
\(O(1)\) 修改每个块其实打个标记,因为一定会推到,所以修改量就是查询量。
K.Communication Towers
难以删除,线段树分治,但是难以标记点是否连通。
考虑建虚点,每次合并把对应连通块连到虚点上,每次删除直接拆掉虚点,下放标记。
还要维护一个路径压缩的并查集,保证复杂度。
L.[ROI 2023] 生产计划 (Day 2)
考虑先求出一个最大独立集,每次选一个点 +1,发现每次只能变化 1。
先求最大和最小情况下的最大独立集,显然中间的部分一定能构造出来。
考虑每个点增加对答案的影响,这东西的变化函数一定是先不动在斜率为 1。
动态维护最大独立集可以动态 dp,上树维护。
I.[北大集训 2021] 小明的树
没听懂。
J.Train Tracks
可以找到每个必须切换的时间段,这东西就是一个贪心。
但是问题出在首先如何找,其次是区间数量。
但是在最大的情况下一定是不停切换到两边,就是 log 层 \(O(n\log n)\)
可以将火车看作从下往上走,就是启发式合并。
每个点维护 set,找前驱后继就能找到区间。
12.23 奇怪复杂度数据结构
A.[SHOI2006] 作业
看到 x,y 非常小,考虑对值域做根号分治。
对于每个 ky,可以分段,每次找最小的值,set 维护,时间复杂度 \(\frac{V}{y} \log\)
y 比较小的时候可以暴力开桶处理。
B.Magic Triples (Hard Version)
枚举中间的值,如果 \(a_j\ge 10^6\),\(b\le 1000\),否则可以根号枚举因数直接找。
上面这东西是 \(O(nV^{\frac{1}{3}})\) 因为因数个数较少,所以可以再把阈值调高。
C.[Ynoi Easy Round 2015] 此时此刻的光辉
约数个数就是指数 +1 的乘积,这东西显然可以莫队维护,但是暴力维护会超时。
如果按不同的去维护,就是 \(\frac{\log v}{\log v\log v}\)
根号分治,如果质因子比较小,那么可以直接前缀和,时间复杂度就是 \(O(qv)\)
假设阈值为 1000,那么莫队基本上至多 2-3 个 \(O(128q+n\sqrt q+nv^{\frac{1}{4}})\)
D.
一棵 n 个点的树,有 \(c(c\le 15)\) 种颜色,点有颜色,q 次询问,给定一个颜色集合 s 和一个点 v,求保留这些颜色 u 所在连通块大小。
每次找重心分治,每次找每个点到重心的路径信息,然后高维前缀和,然后就炸了。
所以要设定一个阈值,只能前几层跑这个,后面暴力,\(O(n\sqrt {2^c*c})\)。
E.[Ynoi2013] 无力回天 NOI2017
考虑按每个数的出现次数根号分治,新加一个值,会对 k 个集合做 +1 操作。
剩下可以用 bitset 维护超过这个阈值的状态,每次一或, \(O(n\sqrt{\frac{n}{w}})\)
F.
询问区间有多少数出现次数 \(\le k\),强制在线。
额……不能莫队。
区间本质不同的出现次数至多根号种,对整个数列分块。
对于整块 i 到 j,可以维护每个出现次数有多少个,散块暴力。
G.[Cnoi2019] 数字游戏
跑值域线段树维护出现情况,就可以 \(O(n\sqrt n \log n)\)
可以用不删除莫队,对每段 1,维护两个指针,一个从头指向尾,一个从尾指向头,就可以 O(1) 插入。
那么如何查询,可以分块,贡献加在左端点,这样只会算错两部分,修正一下就行了。
H.[Ynoi2013] 文化课
这是区间修改区间查询,先考虑对值的修改,每个位置相当于一个多项式,至多 \(\sqrt n\) 项,加上线段树和快速幂 \(\log^2\)
修改符号是容易记录的,记一下乘积以及和,还要记左右极长连乘,以及多项式。
先考虑一下,可以发现根号是每个块长的根号,所以其实是等比数列求和,线段树没有 \(\log\)。
剩下的快速幂的部分,可以算差或者光速幂,然后就单根号了。
I.「KTSC 2020 R1」穿越
设 \(f_{i,j}\) 表示到 \((i,j)\) 的花费,列间转移看是否阻挡,列中的就是对 \(min+A\) 取 min。
但是不能对每个都跑,所以考虑维护一个 \(xA+yB\) 状物,但是不能维护所有 AB 组合方式。
注意到 \(x+y\le 2n\),这东西可能是一个凸包状物。
手摸一下,19A+19B 一定不会同时优于 20A+B 和 A+20B。
所以一定是在下凸包上的东西才会有贡献,每次加减相当于平移。
线段树就要维护这东西:
pushup:\(O(点数)\) 合并儿子。
update:\(O(点数)\) 取 min。
但是可以发现坐标是整数且两维大小都是 n,有个结论就是只有 \(n^{\frac{2}{3}}\) 个点。
神经病题****。
J.[Ynoi2006] rmpq
B 个矩形会将平面分成 \(B^2\) 个区域,所以可以定期重构,大概 \(O(n^{\frac{5}{3}})\)。
可以将平面划分成一些网格,这东西可以通过分治来实现,考虑如何合并网格。
合并两个分治结果是 \(n^2\) 的,总复杂度为 \(O(n^2)\)。
询问就是定位在每个块的位置,然后散块暴力,\(O(n\sqrt n)\)。
I.qoj1851
这东西可以先做 DAG 可达性,必然时间复杂度不会低于 \(O(\frac{n^2}{w})\)。
按 w 分块,每 w 次重构一下,那么每次重构要线性。
先考虑块内,因为处理了可达性,可以 \(O(1)\) 查。
接下来是重构全图,如果最后是修改,那么前面的取 min 都没有贡献了。
首先要对每个点求最后被修改的时刻,修改就可以直接 topo 排序。
取 min 可以拿出来排序,如果一个点被多次取,那么只有最小的生效。
可以记一下操作时间,然后用一个 bitmask,每次把时间不合法的部分改为 0,同时可以知道哪些取 min 有效。

浙公网安备 33010602011771号