lxl 又又来讲课记录

Day1

似乎是模拟费用流,鸽子一下。

Day2

模拟费用流部分鸽掉了。

Ynoi Easy Round 2019 T3 神木辉

image

首先考虑不存在一操作怎么办,直接莫队,然后对于每个集合维护答案,可以做到 \(O(n\sqrt m)\)

如果存在一操作,考虑套用类似天降之物的做法,对于每个集合维护附属集合大小,如果达到 B 就重构,每次重构之间跑莫队,复杂度 \(O(n\sqrt{\frac {mB}n}\times \frac n B+mB)=O(n^{\frac 5 3})\)

P11369 [Ynoi2025] 弥留之国的爱丽丝

考虑根号重构,每 B 次操作重构一下,考虑每次把边中间涉及到的点拉出来建边,然后压位 bfs ,复杂度 \(O(\frac {nm}w+m(B+\frac {B^2}w))\),只需要 \(B\ge 64\) 即可。

P11831 [省选联考 2024] 追忆

考虑同时维护每个点维护一个关于 \(a\) 的分块,然后根号重构,设块长为 B,重构时间是 T,则复杂度是 \(O(\frac {nm}w+\frac m T\times n\times \frac n B+m(B+T))=O(\frac {nm}w+n^{\frac 5 3})\)

QOJ# 1851. Directed Acyclic Graph

你先别急,鸽。

P9933 [NFLSPC #6] 9.pop_back();

每次找到相邻两个之间,谁超了谁即可,堆维护。

未公开题目

数轴上有 \(n\) 个线段,左端点固定,右端点分别以不同的固定速率向右移动。
\(m\) 次询问,每次询问给定时刻 \(t\),求 \(t\) 时刻所有线段的并的长度。
\(m \le 10^6\)

考虑维护连续段之间被爆的时间,和连续段之间被爆的时间,堆维护。

CF704E Iron Mann

树剖,变成若干线段,找到相邻两个之间什么时候相遇即可。

BZOJ4700 适者

邻项交换,然后李超线段树维护贡献即可。

CF1303G Sum of Prefix Sums

点分治+李超线段树即可。

哈夫曼树合并加上建凸包可以做到一个 \(\log\)

未公开题目

一张 \(n\) 个点的图。
\(m\) 组边, 每组是从点 \(c\)\([l,r]\) 连边, 指向 \(y\) 的边边权为 \(ky + b\)
\(1\) 号点出发到所有点的最短路
\(n, m \le 10^5\) , 保证所有边权非负

dijkstra,需要支持插入直线,用然后每次取出代价最小的即可,线段树套李超线段树即可。

Day2

P5073 [Ynoi Easy Round 2015] 世上最幸福的女孩

首先转成全局加正数。

考虑做闵可夫斯基和,但是这个题不满足是凸的怎么办,考虑由于我们没有限定长度一定要为多少,所以非凸的位置都是不必要的,然后我们就可以做了。

由于要求空间线性,所以我们分成 \(O(\log n)\) 块做即可。

P11343 [KTSC 2023 R1] 出租车旅行

首先一个做法是考虑 dijkstra + 点分树 + 李超线段树,但是这个不好写。

首先我们一定是从 \(a\) 大的跳到 \(a\) 小的,按这个顺序转移即可,这个只需要查询单点,好些。

AT_dwango2016qual_e 花火

这个似乎直接 slope trick 即可。

P11235 [KTSC 2024 R1] 最大化平均值

有点困难,鸽。

P3765 总统选举

直接摩尔投票即可。

P8496 [NOI2022] 众数

摩尔投票+链表+线段树合并即可。

P4062 [Code+#1] Yazid 的新生舞会

考虑统计每个点作为绝对众数的区间,对于每种颜色,对于每个点找到前面一个点,后面一个点,连同这个点一起删掉,那么这些点形成的区间的子区间就是可能有贡献的,然后我们考虑由于我们每次权值只会 \(\pm 1\),所以可以 \(O(n)\) 计算逆序对,套用线性并查集,整个题可以做到 \(O(n)\)

P8349 [SDOI/SXOI2022] 整数序列

有结论:

复杂度与 \min 相关的询问
\(m\) 个集合, 大小分别为 \(S_1, S_2\ldots S_m\)。 设 \(n=\sum_{i=1}^mS_i\)
\(q\) 次询问, 处理询问 \((x,y)\) 的复杂度为 \(O(\min(S_x,S_y))\)
若将询问记忆化,则总复杂度为 \(O(n\sqrt q)\)

套在这个题目上面即可,使用线性并查集,复杂度 \(O(n\sqrt q)\)

P7882 [Ynoi2006] rsrams

考虑根号分治,\(cnt\) 大的部分,我们启动莫队,复杂度 \(O(cnt\sqrt m+ m)\)

\(cnt\) 小的部分,考虑找出所有可能成为绝对众数的区间,会找出 \(O(cnt^2)\) 个区间,总区间个数 \(O(ncnt)\),用 \(O(1)-O(\sqrt n)\) 分块即可。

不难发现,对于后者保留所有寻找区间即可做到线性空间,复杂度 \(O(n\sqrt m+(n+m)\sqrt n)\)

Day4

QOJ8704. PKUSC2023 D2T1 排队

直接 FHQ 维护 dfn 序即可。

QOJ8229. PKUWC2024 D2T3 栈

似乎直接单侧递归即可,套用 CF1340F,记录合并的时候抵消的贡献。

QOJ8672. PKUSC2024 D2T2 排队

直接套用插入-标记-回收算法即可。

QOJ9676. PKUW2025 D2T2 Ancestors

lxl 做法有点神奇,感觉不如每层做颜色段均摊。

P11622 [Ynoi Easy Round 2025] TEST_176

插入-标记-回收算法,平衡树有交合并复杂度是 \(O(m\log n\log V)\) 的,考虑令势能为 \(\sum \log (a_{i+1}-a_i)\),则势能上限不会超过 \(O(n\log V)\),每次插入一个数增加 \(O(1)\) 势能,花费 \(O(\log n)\) 代价。

详细证明可以看这里: zx2003 的博客

P9999 [Ynoi2000] tmostnrq

插入-标记-回收算法,对于原树剖一下,则除了到根路径上的 \(O(\log n)\) 条轻边可能是从上往下跳之外,剩下所有点都是从下往上跳,最多跳 \(O(\log n)\) 次,每次切换重链是 \(O(\log m)\) 的,复杂度 \(O((n+m)\log m\log n)\).

未公开题目

给出一棵 \(n\) 个点的树。 其中第 \(i\) 条边连接节点 \(u_i,v_i\),边权为 \(w_i\)
每个节点都有一种颜色。 其中第 \(i\) 个点的颜色为 \(c_i\)
定义一个连通块的权值为里面所有点的颜色种数。
共有 \(q\) 次询问。 每次询问给出 \([l,r]\),查询保留边权在 \([l,r]\) 中的边后,所有连通块的权值和。
\(1 \le n, q \le 10^6\)

不知道从哪里出来把 lxl 打到半夜的题目。

对于每个颜色分开考虑,然后点边容斥,不难发现,此时答辩的部分是会出现只有虚点的连通块,怎么把这部分贡献删除。

这个时候,对他做代表元,考虑每个点什么时候作为虚点连通块最浅的点,然后发现我们构成了一个阶梯状的东西,然后每次计算完贡献之后一定会存在推平,所以均摊只有 \(O(n)\) 次操作,找出来通过可以线段树合并。

Day5

P8337 [Ynoi2004] rsxc

发现每个点就是线性基和颜色为 \(2^k\) 的部分的交。

每个贡献区间差分,然后发现单调移动,可以然后矩形求和就可以 \(O(n)\) 预处理后做到 \(O(1)\) 询问,由于有 \(O(\log n)\) 个区间,复杂度 \(O((n+m)\log n)\)

P11210 『STA - R8』强制在线动态二维数点

同样考虑偏序的不优,维护区间最大值,然后线段树二分即可。

P9057 [Ynoi2004] rpfrdtzls

考虑 \(x\not=1\),然后对于下标扫描线,线段树维护时间维,维护历史版本和,然后一次插入删除只会影响到 \(O(\log V)\) 个连续维护,连续位置修改是 \(O(len+\log n)\) 的,所以这个部分是单 \(\log\)

然后考虑对于 \(x=1\) 的部分,在叶子里面缩起来,集体打 tag 即可。

T365455 小粉兔询问

扫描线左往右扫 \(r\),每次维护每一个位置被包含的最大的 \(l\) (当前都只考虑了右端点 \(r\) 的区间)。
于是每次询问查询 \([l,r]\)\(\min\),判断是否 \(= l\) 就可以了。
区间修改取 \(\max\),询问区间 \(\min\),直接维护即可。
时间复杂度 \(O(n\log n)\)

P11695 [JRKSJ ExR] 昼寝

首先我们考虑对于 \(x\) 维分治,考虑对于询问做二区间合并,那么我们需要考虑两个部分。

一个是跨过区间的区间的贡献,这个可以按时间扫描线,然后插入删除,维护 \(满足 L\ge ql,R\le qr\) 的最大 \(R\),线段树对于每个 \(R\) 维护最大 \(L\)

然后剩下在两个区间内部的部分,可以从中间往两端扫描线,或者从两端往中间,前者需吉司机线段树,所以我们考虑从两端往中间扫描线。

线段树维护时间维度,在 \(qr\) 插入,然后每次一条被区间完整包含的部分,就可以直接将这段时间的进行一个 "推" 的操作,既对于 \(L\)\(\min\)

如果当前扫描线已经达到 \(i\),且不能推,把这个数拿出来,判断和 \(L\) 的关系,就可以得到是否合法。

这个题分治作用大概是砍掉了 \(x\) 维的一个自由度,使得可以对于另外一个自由度扫描线。

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

考虑分治,然后考虑对于一边,如果中间存在另外一边的数是 \(|x+y|\),否则是 \(|x-y|\),然后随便做一下即可。

P7220 [JOISC 2020] 掃除

二进制分组,然后跑 P9061 平衡树维护轮廓线即可。

P11721 [清华集训 2014] 玄学

二进制分组,每个长度为 \(len\) 的节点只有 \(O(len)\) 个等价类,直接做即可。

UOJ191 【集训队互测2016】Unknown

套用上面做法,每层最后一个节点不建出来即可。

Day6

UOJ218. 【UNR #1】火车管理

随便维护一下历史信息。

CF888G Xor-MST

傻逼题

AT_cf17_final_j Tree MST

傻逼题

CF1550F Jumping Around

傻逼题

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

傻逼题

P4565 [CTSC2018] 暴力写挂

拆一下式子,然后树分治+建虚树即可。

P6199 [EER1] 河童重工

考虑点分治后每层怎么找 MST,对于每条边,找到两端最近的关键点,然后连边即可。

P8260 [CTS2022] 燃烧的呐球

傻逼分讨题,码量巨大。

P3703 [SDOI2017]树点涂色

颜色段均摊摊一下。

P7735 [NOI2021] 轻重边

树剖板子。

QOJ9694. Light Drinking and Low Singing

不会做,鸽

Day7

P10786 [NOI2024] 百万富翁

交互题,可以 dp 出来最优决策。

UOJ52 【UR #4】元旦激光炮

经典老番

P8984 [北大集训 2021] 末日魔法少女计划

不要看成图,看成 \([l,r)\) 的区间信息就好了,然后也是 dp,比较复杂。

U474561 Ynoi Easy Round 2018 T2 星野爱久爱海

定长分块,然后直接贪。

P6780 [Ynoi2009] pmrllcsrms

定长分块,然后分讨。

P9478 [NOI2023] 方格染色

斜线数量少,直接分讨。

P11621 [Ynoi Easy Round 2025] TEST_139

修改差分成为三角形和 2sat 矩形,然后询问差分成为单点,然后 cdq 分治维护。

P8259 [CTS2022] 回

变成八个三角形,然后按上面的方法差分即可。

P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II

莫队二离板子。

P6774 [NOI2020] 时代的眼泪

困难,鸽

P11348 [KTSC 2023 R2] 团队建设

对于一个序列分块,计算每个数和这块内的数的最大贡献,直接跑决策单调性即可,然后需要一个 \(O(n)-O(1)\) rmq,对于散块对整块,似乎反过来算一下,然后散块对散块,直接决策单调性。

Day8

Luogu2824 [HEOI2016]排序

ODT+ 线段树合并+ 线段树分裂即可。

P9995 [Ynoi2000] rspcn

ODT 的时候维护每个值是否第一次出现,然后外面套一个 bit 维护每颗树第一次出现的数有多少即可。

P5612 [Ynoi2013] Ynoi

ODT + Trie 分裂合并,还需要写压缩 Trie 保证线性空间。

P6018 [Ynoi2010] Fusion tree

只维护儿子节点即可。

P11160 【MX-X6-T6】機械生命体

Trie 树 +v,分裂合并。

CF1515H Phoenix and Bits

维护子树内是否存在界定啊既存在往右和往左的边,然后直接均摊 \(O(n\log V+m\log^2V)\)

U172635 PKUSC2019 D2T1

似乎直接线段树合并,注意判断有一个节点为空的时候转移的权值。

P6773 [NOI2020] 命运

线段树合并优化 dp 板子。

P3316 [SDOI2014] 里面还是外面

考虑射线法,计算一个点往上经过多少条线段。

考虑树套树,第一维按 \(X\) 分治,然后此时我们询问的是一个单点,在到根路径上的 \(O(\log V)\) 个节点上查询即可,我们发现需要查有多少个线在这个点上方,然后直接半平面修改查询(雾

发现这些线段不交,所以有一个相对顺序,平衡树维护,在上面二分即可。

P11370 [Ynoi2024] 堕天作战/虚空处刑

uob 太牛逼了

还是考虑树套树,然后发现我们询问的 x 维是区间,考虑询问作为子孙和作为祖先的贡献。

  • 作为子孙,发现祖先节点还是满足线段不自交,平衡树维护,然后二分,找到是否有交。
  • 作为祖先,发现下面的部分有两种情况:形成锯齿或者形成一个类似耳的不跨过区间的部分。

形成锯齿的也满足不自交,如果跨过锯齿平衡树维护,不跨过发现只有上下两个可能有交,维护凸包 check 即可。

至于耳,我们考虑扫描线,然后维护凸包,判断是否和凸包有交即可。

Day9

可持久化平衡树

这里只讲 Treap,因为其他的不会。

考虑合并的时候,用 \(\frac {a}{a+b}\) 的概率让 \(a\) 作为根。

分裂的时候直接类似把涉及到的复制一份,剩下的指针移过去即可。

然后我们还是考虑 \(O(\frac n{\log n})\) 次操作重构一下,空间复杂度 \(O(n)\),复杂度几乎不变。

然后最厉害的一点是可以做区间复制,结果我写的似乎有问题,能在 \(n=10^4\) 的情况树高跑到 \(400\),非常震撼。

当然由于区间复制若干次后,长度变成指数级,一次操作会变成 \(O(n)\),危险,所以一般会限定长度。

例子是这个,但是无法通过讨论区 hack。

然后可持久化平衡树可以作为标记下传或者作为信息合并,下面会看到应用。

HDU 6087 Rikka with Sequence

区间复制 k 次,考虑倍增。

CF702F T-Shirts

考虑倒着 dp,可持久化平衡树优化。

Hdu5118 GRE Words Once More

直接做即可。

BZOJ3946 无聊的游戏

考虑维护相邻两项的 lcp,然后发现只有 \(O(1)\) 项的需要重新统计,线段树套可持久化平衡树作为标记,维护哈希,然后二分 lcp。

QOJ8229 PKUWC2024 D2T3 栈

直接线段树套可持久化平衡树即可,可持久化平衡树维护标记下传。

CF1340F Nastya and CBS

作为信息上传,维护左右两边的左右括号,如果无法匹配小的那边的长度直接判定为 -1,否则都删去对应长度,合并。

建树复杂度 \(T(n)=2T(\frac n 2)+O(\log n)=O(n)\),每 \(O(\frac n {\log^2 n})\) 次操作重构,空间复杂度线性,时间复杂度从 \(O(n+m\log^2 n)\) 变成 \(O((n+m)\log^2 n)\)

如果不匹配仍然有信息,暴力做法是二分 lcp,似乎复杂度变成 \(\log^3\),不知道单侧递归是否能做。

注意这里定义跟上面的一样必须是两个相邻括号才能删除

糊了一下,发现单侧递归变成 \(T(n)=2T(\frac n 2)+O(1)=O(n)\) 了,看起来爆干净了。

P8264 [Ynoi Easy Round 2020] TEST_100

套用线段树式的二进制分组,每部分用可持久化平衡树。

卡常可以下面若干层暴力,上面若干层不计算。

P10214 [CTS2024] 投票游戏

考虑轻儿子完后考虑重儿子的贡献,发现是分常数段常函数,直接 ddp 即可。

HDU6843 Query on the Tree

一个做法是对于在树上 dfs,分块维护时间维度,那么每次我们需要前缀求和,区间 ckmax,撤销,直接做时空都是 \(O(n\sqrt {n\log n})\) 的。

考虑树分块,然后对于一个块那个堆维护到根路径上所有点的集合,对于每个块维护一个序列,然后每个块维护一个数组,然后后端插入。

如果修改在这个块内,我们就可以直接重构这个块内所有点的贡献,累加一下历史和,然后修改。

发现上面部分都可以使用线性并查集和基数排序等方式离线去掉 \(\log\)

CF1344E Train Tracks

考虑启发式合并寻找到所有需要改的时间,然后贪心即可。

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

首先考虑哪些节点会对询问的 \(x\) 产生贡献,分成几类。

  • \(x\) 的子树内部节点。
  • \(x\) 的祖先。
  • \(x\) 没有祖先后代关系的节点。

第一类和第三类是容易计算的。

我们考虑如何计算第二类的贡献,考虑 \(y\)\(x\) 产生了贡献。

  • \(c_y=-1\),此时 \(x\)\(y\) 的子树内部即可。
  • \(c_y=0\),此时需要满足 \(x\)\(y\) 的右子树内部。

我们可以把贡献看成在边上。

考虑对于原树进行 top cluster 树分块,那么 \(x\) 到根的路径可以表示成 \(O(\sqrt n)\) 条簇路径的贡献+ \(O(\sqrt n)\) 个散点的贡献。

对于修改操作使用颜色段均摊,则我们只有 \(O(n+q)\) 次区间染色。

散点的颜色可以用 \(O(\sqrt n)-O(1)\) 的分块维护。

我们将染色操作带上 \(\pm 1\) 的贡献系数,表示染色或者删除之前的染色。

对于整块,我们需要一次染色操作带来的贡献,我们对于每个块,对于簇路径用桶维护出现节点有哪些,以及在簇路径上经过向右儿子的边的节点有哪些,对于桶做前缀和,那么我们可以 \(O(1)\) 计算出来 \([l,r]\) 在簇路径上有多少个节点,那么我们一次染色对于一个块的影响可以 \(O(1)\) 得到,所以我们就可以在 \(O((n+q)\sqrt n)\) 的复杂度内解决,但是常数不是很小。

P8990 [北大集训 2021] 小明的树

点边容斥即可。

Day10

在线莫队是 \(O(n^{\frac 5 3})\) 的。

P10789 [NOI2024] 登山

折戟沉沙,后面忘了,总之 lxl 伟大。

考虑 dp,发现我们应该从上到下转移,但是观察我们的贡献系数,发现存在一个节点到当前点的最小的 h 限制,很坏,考虑启发式合并一下,然后记录此贡献系数过程,再倒着 dp 几下。

对于每个 \(r\) 维护 \(l\) 即可,然后 \(h\) 限制等价于一个 \(r\gets \min(r,h)\) 的过程,此时存在一个均摊过程,会合并若干 \(r\),启发式合并即可。

我写的做法似乎是对于每个重链从上到下单独考虑,然后不断插入轻儿子的节点,总插入次数是 \(O(n\log n)\) 的,那么就不大能继续启发式合并了,否则会变成 \(O(n\log^3 n)\),所以我把每个线段的 \(l,r\) 分开维护,\(r\) 进行推平,如果 \(h<l\) 了,就把这些 \(l\) 的贡献删掉。

问题大概是启发式合并的时候可以同时统计子树信息,但是每条重链从上到下单独做就不能利用轻儿子信息,但是从下往上做似乎是可以的。

贴个代码

Code
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=1e5+5,H=998244353;
int Tim,T,n,f[N],p[N],dl[N],dr[N],h[N],son[N],sz[N],d[N];
namespace ST{
	int t[N<<2],sum[N<<2],tag[N<<2];
	#define k1 (k<<1)
	#define k2 (k<<1|1)
	#define mid ((l+r)>>1)
	#define ls k1,l,mid
	#define rs k2,mid+1,r
	inline void up(int k){t[k]=(t[k1]+t[k2])%H,sum[k]=(sum[k1]+sum[k2])%H;}
	inline void add(int k,int v){tag[k]=(tag[k]+v)%H,t[k]=(t[k]+1ll*sum[k]*v)%H;}
	inline void push(int k){if(tag[k]) add(k1,tag[k]),add(k2,tag[k]),tag[k]=0;}
	inline void upd(int x,int v,int k=1,int l=1,int r=n){
		if(l==r) return sum[k]=v,t[k]=v*tag[k]%H,void();
		push(k);
		if(x<=mid) upd(x,v,ls);
		else upd(x,v,rs);
		up(k);
	}
	inline void change(int L,int R,int v,int k=1,int l=1,int r=n){
		if(L>R) return;
		if(L<=l&&R>=r) return add(k,v);
		push(k);
		if(L<=mid) change(L,R,v,ls);
		if(R>mid) change(L,R,v,rs);
		up(k);
	}
}
vector<int>Tr[N];
inline void dfs(int x){
	sz[x]=1,son[x]=0;
	for(auto v:Tr[x]) dfs(v),sz[x]+=sz[v],son[x]=sz[v]>sz[son[x]]?v:son[x];
}
struct info{int l,r,c,t;}st[N<<2];
int top,Now;
map<int,int>mp,lp;
inline void ins(int l,int r){
	if(l<=r) st[++top]={l,r,1,Now},ST::change(l,r,1),mp[r]++,lp[l]++;
}
inline void find(int x,int mn){
	mn=min(mn,h[x]),ins(dl[x],min(dr[x],mn));
	for(auto v:Tr[x]) find(v,mn);
}
inline void maintain(int val){
	while(mp.size()&&(*mp.rbegin()).first>val){
		int x=(*mp.rbegin()).first,v=(*mp.rbegin()).second;
		mp[val]+=v,mp.erase(x),st[++top]={val+1,x,-v,Now},ST::change(val+1,x,-v);
	}
	while(lp.size()&&(*lp.rbegin()).first>val){
		int x=(*lp.rbegin()).first,v=(*lp.rbegin()).second;
		lp.erase(x),mp[val]-=v,st[++top]={val+1,x-1,v,Now},ST::change(val+1,x-1,v);	
	}
}
inline void solve(int R){
	vector<int>vec;
	mp.clear(),lp.clear();
	for(int i=R;i;i=son[i]) vec.pb(i);
	for(int x,i=(int)vec.size()-1;~i;--i){
		Now=x=vec[i];
		if(x==1) continue;
		ins(dl[x],min(dr[x],h[x]));
		for(auto v:Tr[x]) if(v!=son[x]) find(v,h[x]);
		maintain(h[x]);
	}
	for(auto x:vec){
		if(x==1) f[x]=1;
		else f[x]=ST::t[1];
		ST::upd(d[x],f[x]);
		while(st[top].t==x) ST::change(st[top].l,st[top].r,-st[top].c),--top;
	}
	assert(!top),assert(!ST::t[1]);
	for(int x,i=(int)vec.size()-1;~i;--i)
		for(auto v:Tr[x=vec[i]]) if(v!=son[x]) solve(v);
}
inline void solve(){
	cin>>n,d[1]=f[1]=1;
	for(int i=1;i<=n;++i) Tr[i].clear();
	for(int l,r,x,i=2;i<=n;++i) 
		cin>>p[i]>>l>>r>>x,Tr[p[i]].pb(i),d[i]=d[p[i]]+1,dl[i]=d[i]-r,dr[i]=d[i]-l,h[i]=d[i]-x-1;
	dfs(1),solve(1);
	for(int i=2;i<=n;++i) cout<<(f[i]+H)%H<<" ";
	cout<<"\n";
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>Tim>>T;
	for(int i=1;i<=T;++i) solve();
}

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

和 P7600 [APIO2021] 封闭道路 一个 trick。

维护度数从小到大计算 \(i\),只保留 \(\text{deg}\ge i\) 的点的虚树即可。

P11111 [ROI 2023] 生产计划 (Day 2)

鸽了。

P11163 [BalkanOI 2023] Weights

对于叶子考虑贡献即可。

P10151 [Ynoi1999] SMV CC-64“蝰蛇”

对于置换环重新标号使得其连续,首先修改我们可以找出若干个合法极长连续段,特判掉两端跨过区间的 \(O(1)\) 个。

然后我们考虑一个连续段的贡献,就是在区间中满足 \(ql\le l,r\le qr\) 的时候,且在置换环上的区间包含 \(pos_x\) 的时候,存在 \(r-l+1\) 的贡献。

但是由于不同区间不交,所以我们只需要考虑 \(ql\le l\le qr\) 即可,注意 \(qr\) 要变成 \(qr'\) 使得其不存在右边那个跨过区间的贡献。

似乎对于下标维开树套树就要区间取 \(\max\),区间删除操作,不大好做,对于置换环那一维度开树套树,那么我们只需要单点修改即可,区间询问 max,这个很好做。

然后就是 \(O((n+m)\log^2 n)\) 了。

P5344 【XR-1】逛森林

ST 表优化建图。

P7712 [Ynoi2077] hlcpq

拉一个以前的题解:

首先对于这个题,我们考虑优化建图,那么我们比如对横着的线段按 \(y\) 扫描线,那么就是在每个竖着的线段在一段时间内单点存在,我们相当于插入删除,但是由于建图连边是不容易删除的,我们可以新开一个版本,然后在新版本上修改后连边。

现在的问题是我们直接做是不行的,因为虚点可能改变原图的双连通性,我们考虑不建出虚点,考虑 Tarjan 算法流程:

  • 遍历所有未遍历的点,这个我们可以主席树上每个节点维护这个区间内有多少个点未被经过,这里有个性质,就是对于每条线段,其在主席树上的叶子对应的都是同一个,所以不会出现一个点跑多遍的情况。
  • 找到所有能到达的点的 dfn 最小值,由于对于每个点,他能到达的点是一个版本的一段区间,这个可以直接询问即可。

然后这个题就可以做到 \(O((n+m)\log n)\)

P6019 [Ynoi2010] Brodal queue

对于整块打 tag,散块颜色段均摊,然后自己随便推一下,似乎不是很难。

\(f_{i,j}\) 表示第 \(i\) 块到第 \(j\) 块贡献,后面似乎是简单的。

posted @ 2025-04-14 20:51  Nityacke  阅读(358)  评论(0)    收藏  举报