5 月记录

P12030 [USACO25OPEN] OohMoo Milk G

\(A\) 大的数集合不会变化。

考虑变化思路,先将加法算上,那么最后变成每个数最多可以减 \(D\) 次,总共能减 \(BD\) 次。

不难发现这样是对应的,然后二分即可。

P11803 【MX-X9-T7】『GROI-R3』此花绽放之时

妙妙题。

考虑将线段树懒标记的思想搬到这里来。

考虑将标记放到每个极大同色联通块最浅节点。

标记是如果节点颜色为 \(c\),就加上 \(x\)

然后链修改的时候,将 \(u,v\) 到根的标记都下传,且颜色相同的标记可以合并。

每次只下传在父亲上的,当前节点颜色的标记。

注意,在更新 \(u,v\) 路径颜色为 \(x\) 时,为了防止之前已有的关于 \(x\) 的标记下传,我们也需要更新路径上所有作为轻儿子的 \(w\)\(c_{x,w}\) 的值。

然后考虑树剖优化,每次给一个点打标记时,将其重链上所有应该打标记的节点都打上标记,然后定义下传标记只往轻儿子下传。

但是这样下传的复杂度是度数级别的,我们考虑只下传对应的轻儿子,同时为了避免重复下传,记一个 \(c_{x,u}\) 表示 \(u\) 上次从父亲获得颜色为 \(x\) 的标记的值,每次扣掉这个才是新加的真实值。

每次链修改颜色就对重链维护一个 odt 推平即可。

时间复杂度 \(\mathcal O(n\log^2n)\)

这种标记思想就保证了在没有修改的时候,你查询一个点,往下推标记时对的。

然后有修改的时候,因为同色联通块是联通的,先将之前的标记下放,再将路径上的之前打的对应当前修改颜色的标记阻断,这样就保证了子树内的标记是真实的。

P11087 [ROI 2019] 考古 (Day 2)

用可持久化平衡树维护字符串 \(t\),这样可以做到最后只有 \(O(s+n \log t)\) 的节点。然后我们需要快速统计跨过两个节点的出现次数。

对于每个节点,如果我们能维护它的最长前缀是 \(p\) 的后缀,以及它的最长后缀是 \(p\) 的前缀。那么跨过两个节点的出现次数就可以在 \(p\) 的前缀 KMP 树以及后缀 KMP 树上查询得到,就是树上两条路径的交,离线可以 \(O(\log m)\) 得到。

但是不好维护,考虑维护最长前缀/后缀是 \(p\) 的子串,那么对应的 \(p\) 的前后缀可以在前缀 KMP 树以及后缀 KMP 树上倍增得到。不妨考虑最长前缀,然后会涉及到两个节点合并后如何维护这个东西。

\(l_p,l_s,r_p,r_s\) 分别表示左边节点的最长前缀对应的字符串,右边节点的最长前缀对应的字符串。如果 \(l_p \ne |l_s|\),那么合并后节点的最长前缀显然就是 \(l_p\)。否则,这些前缀分别对应了 \(p\) 的一个子串,不妨设为 \(p[l_1,r_1]\)\(p[l_2,r_2]\),我们要求出 \(p[l_1,r_1]+p[l_2,r_2]\) 的一个最长前缀是 \(p\) 的子串。考虑求出 \(p\) 的后缀数组,就是其与所有后缀的 LCP 的最大值,二分出这个字符串在后缀数组中的位置 \(x\),那么在 \(x\)的左右两侧和这个字符串求个 \(lcp\) 就是答案。

复杂度 \(O((s+n \log t) \log m)\)

P11038 【MX-X3-T5】「RiOI-4」Countless J-Light Decomposition

不妨 dp 子树最小的轻边和,在 \(u\) 处合并就是取第 \(i+1\) 大的值上来。

不难发现之后 \(son_j\ge i\) 的点有用,拿出来建虚树,总点数是 \(\mathcal O(n)\) 的。

但是虚树上点的非虚树儿子有贡献,拿平衡树维护即可。

P3822 [NOI2017] 整数

实现一个 \(b\) 进制的计数器。

正常只有加法的时候是均摊线性的。

但如果有减法势能就不对了。

考虑限制位上的值在 \((-b,b)\),发现此时进位、退位都是 \(1-b\to 0\)\(b-1\to 0\),将非 \(0\) 位个数当作势能就对了。

然而现在要查询原数某一位,如何来还原原数的一位呢?我们发现进退位对于下一位的影响总是 \(+-1\) 的,我们只需要找到我们当前查询的位的严格非零前驱,判断一下它是否为负,如果是当前位就需要 \(−1\) 然后输出。

然后将 \(T=62\) 位压位,这样修改就只涉及两位,且 \(B=2^{62}\),容易还原二进制下的某一位。

时间复杂度 \(\mathcal O(\frac{30n\log n}{T})\)

P11027 [COTS 2020] 餐厅 Restoran

绝世难题。

P11081 [ROI 2019] 自动驾驶 (Day 1)

考虑能走的路径形成一张路径网络,于是最短路的形态很少,讨论一下就行了。

P11622 [Ynoi Easy Round 2025] TEST_176

插入标记回收。

\(l\) 处插入 \(x\),中间讨论平衡树有交合并,在 \(r\) 处调用节点编号对应的值即可。

注意平衡树有交合并时,若 \(y\) 中存在与 \(x\) 相同的数,需要使用并查集将它们并在一起,否则复杂度不对。

时间复杂度 \(\mathcal O(n\log n\log V)\)

仙人掌(color)

考虑对每一种颜色分别统计答案。

对于一种颜色,先建出虚树。

可以先处理出在边权 \([l,r]\) 范围内虚树上的联通块数量变化情况,这个是点边容斥,\(\mathcal O(n)\) 次的。

但是会存在只含虚点的联通块,需要减掉。

考虑每一个联通块一定存在一个唯一的在点分树上最浅的点,且其他点都在这个点的子树内,否则两个点在点分树上不交子树内,由于是联通块,它们和 LCA 的路径一定联通。

考虑虚点贡献默认为 \(-1\),如果一个虚点可以连接到任意祖先节点或者子树内任意实点时贡献为 \(0\),即若查询区间包含任意这些区间时,就有影响,那么这些区间去掉被偏序的以后会剩下不相互包含的区间。

然后不会分析了,可以说明去掉后的区间数量是 \(\mathcal O(n)\) 的。

P5612 [Ynoi2013] Ynoi

考虑对有序段进行颜色段均摊。

线段树先维护每个段的标记。

当要合并的时候,分裂左右端点处的 trie,并将中间的 trie 打上对应的标记,在合并起来即可。

分裂合并的复杂度是和线段树合并分裂复杂度相同的。

P11367 [Ynoi2024] 魔法少女网站第二部

考虑猫树分治。

如果询问 \([x,y]\),先处理出在右边区间内的相邻对,如果左半区间不存在在其中的数,则贡献为 \(|i-j|\),否则贡献为 \(i-mid+j-mid\),发现这样左右就近乎独立了,只需要对左右两半分别处理这些对的贡献即可。

考虑扫描线,以右边为例,如果从左往右扫,就需要插入对,这是不好处理的。

考虑反过来,变成删除对,发现这样直接链表就处理完了,中间的贡献用树状数组维护。

时间复杂度 \(\mathcal O(n\log^2n+q\log n)\),可以平衡到 \(\mathcal O(\frac{(n+q)\log^2n}{\log\log n})\),不过更慢了。

P11094 [ROI 2021] 砍树 (Day 2)

对于这一类区间操作统计合法点数的问题,不妨考虑对点计数而非模拟过程。

考虑求 \(L_i\) 表示 \(i\) 向左倒下,需要询问的 \(l\) 的最大值,然后你发现左右独立了,然后每棵树也独立了!!!!妈的!!!!

维护变量 \(j\) 表示当前考察的需要砍掉的数的下标。显然有 \(a_i−h_i<a_j\)。考虑若 \(a_j+h_j\le a_i\),由于其右侧所有树均已经被砍倒,可以令其往右倒下,接着考虑 \(j−1\);否则砍倒 \(j\) 需要 \(L_j\) 及右侧的全部被砍倒,直接考虑 \(L_{j−1}\)。由于 \(L\) 数组有包含关系,我们显然只需要考虑 \((a_i−h_i,a_i)\) 区间内所有满足 \(a_j+h_j>a_i\) 的点中 \(L\) 的最小值,并将其与原始范围取 \(\min\)。第二个条件可以通过把点挂在 \(a_j+h_j\) 处消去,于是使用线段树维护单点修改区间最小值即可。\(R\) 的求法是类似的。

另一种求法是整体二分,枚举 \(l\),从 \(l\) 出发用栈模拟每棵树,判断每个树能不能向左砍就知道 \(L_i\ge l\) 是否成立。

最后的计算就是一个简单的数点了。

P11095 [ROI 2021] 旅行 (Day 2)

点双存在经过一个点与一条边的点不重复简单环。

点双存在经过 \(x\to e\to y\) 的点不重复简单路径,\(x,y\) 是点,\(e\) 是边。

点双存在经过 \(x\to z\to y\) 三个点的点不重复简单路径。

可以推出,边双存在经过 \(x\to e\to y\) 的边不重复简单路径。

边双存在经过两个点的边不重复简单环。

边双存在经过一个点与一条边的边不重复简单环。

边双存在经过 \(x\to z\to y\) 三个点的边不重复简单路径。

而这题是说边不重复。

所以我们考虑枚举最大值,加入 \(\le \max\) 的边,查询最小的可以经过的边,就是在 \(1,u\) 边双路径上的边。

考虑求出每个点在每一时刻到根的最优路径。

每次加边:

  • 连接两个不连通部分,发现这一定是最小生成树上的边,如果其中一部分包含 1 直接遍历另一部分计算当前的答案即可,每个点只会被计算一次,但是需要求 \(1\)\(u\) 所有简单路径上可能的边权最小值,待会再议。
  • 连接一个边双连通分量内部的两个点,由于这条边是最新添加的,所以是当前边权最大的,所以无贡献,直接跳过。
  • 合并了路径上的一些边双连通分量。暴力合并当前收缩树路径上的所有点就行,然后要对新合并出来的点的子树做一次更新。

注意到任意时刻收缩树上的联通块,都一定是以 \(1\) 为根的最小生成树的联通块。那么我们对最小生成树的 DFS 序分别维护子树更新和求到根路径最小值即可。

这样的话操作三,直接在最小生成树上合并即可。

但是,我们可能在一个点还未与 \(1\) 联通时,就更新了最大值,所以我们在当他与 \(1\) 要联通时,删除之前的标记。

P11098 [ROI 2022] 滑梯 (Day 1)

相当于树上求 LCA。

考虑从下往上合并,先预处理出每一层唯一的合并点。

当前层的每个点维护一棵动态开点下标为询问的线段树,每次加入询问,就找到对应点的线段树下标 \(+1\)

当合并的时候出现一个下标值为 \(2\),说明找到了对应下标的 LCA。

时间复杂度 \(\mathcal O(n\log n)\)

CF2077E

观察到等价于选择相邻位置奇偶性不同的子序列 \(-1\)

可以贪心做。

也可以发现,这就是个 dag 最小链覆盖。

建出二分图,考虑 hall 定理。

找到结论就做完了。

P5576 [CmdOI2019] 口头禅

考虑将串中间放一个分隔符,然后给每个串的前缀终止位置标上颜色i,可以换成广义 SAM。

求最大权值的点,使得其子树包含颜色为 [l,r] 的点

考虑按照颜色扫描线,树上每个点维护一个 x,表示其子树内存在 [x,r] 点

然后考虑加入所有颜色为r的点到根的并之外的点,可以表示为nlogn段dfn上的区间,做覆盖r+1

询问就是问x<=l的点的权值最大值,考虑颜色段均摊,每一段 x 相同,维护段权值最大值。

也可以这样做,在树上从下往上合并出连续段,每生成一个连续段,就找到所有被他包含的询问处理掉。

合并过程可以启发式合并。

也可以类似 dsu,先处理完子树,然后再遍历轻子树所有点,如果其所在连续段左右可以合并,就合并,这是单 \(\log\) 的。

P11134 【MX-X5-T6】「GFOI Round 1」Abiogenesis

P11127 [ROIR 2024] 二叉树的遍历 (Day 2)

P12608 骷髅打金服

P10101 [ROIR 2023] 一个普通的字符串问题 (Day 2)

P11151 [THUWC 2018] 明天的太阳会照常升起

对于一种方案调整容易想到。

当存在 \(p_j<p_i\) 时:

* 若 $i$ 能直接到 $j$,直接减去即可。
* 否则加到刚好能到 $j$。

否则,加满,并走到 \(V\)\(p\) 最小的位置。

倍增维护这个过程,发现中间的合并都是能做的。

对于开始的油,倍增跳到第一个无法继续往下或者为二类点的位置。

对于结尾,只需钦定倍增最后跳到 \(V\) 内能走到 \(t\) 的二类点或者下一步 \(>t\) 的二类点即可。

AT_arc198_e [ARC198E] Monotone OR

有一种显性维护分治过程的做法,这种好理解一点。

还有一种直接分治的做法。

https://www.luogu.com.cn/article/xtu5kftp

P12525 [Aboi Round 1] 私は雨

对于 \(p>B\),直接整块预处理前缀块中一种数出现了几次,散块扔到桶里查,可以做到 \(\mathcal O(q\sqrt n+\frac{qV}{B})\)

考虑 \(p\le B\),对数按照 \(\bmod p\) 分类,每一类按照大小排序,拎到一起,问题变成问一个矩形内有多少数。

先转成询问左下角,考虑按下标分成 \(X\) 块,值域分成 \(Y\) 块,对于下标的散块直接扫一遍即可。

对于值域的散块,用上面 \(p>B\) 的做法,是 \(\mathcal O(q\sqrt n+\frac{qV}{Y})\) 的。

然后对所有 \(\mathcal O(\frac{nV}{XY})\) 个整块维护二维前缀和即可。

时间复杂度 \(\mathcal O(q\sqrt n+\frac{qV}{B}+\frac{qn}{X}+\frac{qV}{Y}+\frac{BnV}{XY})\)

时空复杂度 \(\mathcal O(n\sqrt n)\)

P11163 [BalkanOI 2023] Weights

??

P12062 [THUPC 2025 决赛] 列队

查询是查一列排名为 \(x\) 的数。

\(m\le \sqrt N\),直接找到 \(\mathcal O(\sqrt N)\) 次单点修改,然后值域分块,对于每一列维护在某一块的个数,并对每一列维护一个桶。

单点修改一次是 \(\mathcal O(1)\) 的,考虑查询,枚举整块求和,然后确定在哪个块,枚举散块在桶里查询即可。

复杂度是 \(\mathcal O(N\sqrt N)\) 的。

\(m>\sqrt n\),我们希望找出一列的所有值,即每一行相同排名对应的数,然后使用 nth_element 线性求出答案。

枚举每一行,我们希望 \(\mathcal O(1)\) 得到其某一排名对应的数,直接对每一行维护若干个长度相等的块状链表即可,修改就重构散块链表,整块平移,查询先定位块,再定位块内位置即可。

时间复杂度 \(\mathcal O(N\sqrt N)\)

棋无常树

GF 分析组合符号化。

P11203 [JOIG 2024] 感染シミュレーション / Infection Simulation

P12555 [UOI 2024] AND Array

posted @ 2025-05-29 16:00  蒟蒻orz  阅读(42)  评论(0)    收藏  举报