26. 08 做题记录
AT_dp_w Intervals
设 \(f_{i,j}\) 代表考虑 \([1:i]\),上一个黑色在 \(j\),的最大权值。具体来说直接设 \(f_i\) 断点进行转移,形如 \(f_i + w(i,j) \to f_j\),其中 \(w(i,j)\) 代表不被包含在区间 \((l,r)\) 的区间权值和。这个很明显是一个扫描线转移的形式,线段树区间加,区间最小值即可。
P6845 [CEOI 2019] Dynamic Diameter
首先不考虑 LCT,首先考虑到树的直径可以 dp,设 \(f_i\),然后转移为 \(f_u = \max(f_u, f_v + w),g_u = \max(g_v,f_u+f_v+w)\)。那么可以矩阵转移了,然后做 ddp 即可。
哦等等,好像有更聪明的做法。考虑欧拉序。动态直径就是 \(\max(a_j + a_k - 2a_i)\),线段树可以简单合并。
P10833 [COTS 2023] 下 Niz
扫描线,\([l,r]\) 形成一个 \(r-l+1\) 的排列可以表示为,最小值为 \(1\),最大值为 \(r-l+1\),每个数都不同。每个数都不同提供了限制 \(\ge p_0\),最小值为 \(1\) 提供了限制 \(\le p_1\),最后一个限制把每个位置当作 \(a_i+i\),主席树可以维护。
另外一个想法是找出来最小 \(\text{mex}\) 区间,具体来说每次把一个 \(\text{mex}=x\) 的极小区间,找到左右两边的 \(x+1\),扩展到 \(x'\),总数不会超过 \(4n\) 个,最终的个数是 \(2n\) 个。
BZOJ3100 排列
考虑做分治,给每个数赋随机哈希权值,条件就是 \(\bigoplus_{i=1}^{r-l+1} h_i = \bigoplus_{i=l}^r h_{a_i}\)。那么每次分治 \([l,r]\) 时,考虑求出跨 \(mid\) 的答案。假设最大值在 \([l,mid]\) 区间,到另外一边去找是方便的,复杂度 1log。
P8860 动态图连通性
按照删除顺序赋权,给第 \(i\) 条删除的边赋权值 \(2^i\),那么走的是最大权值的路径,这是 CF464E,主席树加上堆维护即可,复杂度 2log。诶我草,怎么可以直接贪,复杂度 1log。
P11585 [KTSC 2022 R1] 直方图
首先考虑 \(k=1\),建立小根树,一定选笛卡尔树上面的一个区间。
接着考虑 \(k=2\),考虑刻画这两个矩形的形态:
-
这两个矩阵都和底边相交:也就是选两个不交的笛卡尔树区间,设 \(f_{i,j}\) 代表考虑 \([1,i]\),选了 \(j\) 个的方案数,转移是平凡的。
-
这两个矩形不都和底边相交,也就是一个在另外一个上面:那么大的一个一定在树上是小的一个的祖先,但是需要扣掉一部分贡献,把答案写出来是:
\[h_u \times l_u + h_v \times l_v - h_u \times l_v \]在 \(u\) 处算贡献,那么贡献的形式是一次函数,可以李超线段树合并来维护。
继续考虑 \(k=3\),同样分类讨论:
-
三个矩形都和底边相交:这个同上。
-
两个矩形和底边相交:记 \(val_u\) 代表以 \(u\) 作为下面的矩形,选两个矩形的答案,和前后缀选一个的答案拼起来即可。
-
只有一个矩形和底边相交,并且三个矩形叠成一堆:同样把贡献写出来是:
\[val_v + h_u \times l_u - h_u \times l_v \]和上面一个维护方式,李超线段树合并即可。
-
只有一个矩形和底边相交,其他两个都和这个矩形相交:写一下贡献,\(i\) 子树选了 \(j,k\) 两个不相交的树上区间,那么贡献为:
\[h_i \times l_i + h_j \times l_j + h_k \times l_k - (l_j + l_k) \times h_i \]考虑到 \(i\) 如果不是 \(j,k\) 的祖先,答案不优,所以把这个限制放掉。记 \(s_i = \max_{l_j + l_k = i} (h_jl_j + h_kl_k)\),那么问题是对于每个 \(i\) 求 \(s_j - j \times h_i\) 的最大值。对偶一下变成很多个点 \((i,s_i)\),拿斜率为 \(h_i\) 的直线去切凸包使得截距最大。
如果没有 \(j,k\) 不交,拿 \((l_i,h_il_i)\) 的凸包自己和自己合并就可以得到这个凸包,比较容易。现在考虑不交的限制。对一个点 \(u\),记其笛卡尔树区间为 \([l_u,r_u]\),记 \(P_u = (l_u, l_u \times h_u)\)。建立线段树,每个节点开两个 vector \(L,R\) 来维护点集。
那么找到线段树上 \(l_u\) 对应叶子到根上的所有点,对是其父亲右儿子的点,在父亲的 \(R\) 加入 \(P_u\)。对 \(r_u\) 同理做,那么两个点 \(u,v\) 就会在 LCA 处分别加入 \(L,R\),所以对于每个点把 \(L,R\) 做凸包合并,然后把所有点加入一个大的点集跑凸包,时间复杂度 1log。
P5972 [PA 2019] Desant
半年前被初见杀的题目。把序列分为两部分,左边一部分大小为 \(B\),把右边一部分划分为 \(B\) 个等价类。但是这样每个等价类内部不方便计算贡献。
因此放弃这个 \(B\),考虑做 dp。考虑 dp 从 \(i\) 到 \(i+1\) 的过程中相当于合并了两个等价类。对于每个 \(i\),状态数是每个等价类大小的乘积,最值大概是 \(O(e^{n/e})\) 的,总状态数是 \(O(ne^{n/e})\) 的,由于每个状态是一个数组,所以总复杂度是 \(O(n^2 e^{n/e})\) 的。
P10069 [CCO 2023] Flip it and Stick it
首先考虑 \(|T|=2\),首先如果 \(T=\texttt{00},\texttt{11}\),那么每个不合法的位置都需要一次操作。如果 \(T=\texttt{01},\texttt{10}\),那么必然会把 \(T\) 操作成 \(\texttt{111000}\) 的样式,答案就是连续段个数,准确来说是 \(\texttt{10}\) 的出现次数。然后对于 \(|T|=3\) 大力讨论:
- \(T=\texttt{000}\):首先合法条件是 \(\texttt{0}\) 的个数比 \(\texttt{1}\) 的个数的三倍再加二少。记 \(\texttt{0}\) 的连续段长度数组为 \(L_i\),那么操作下界是 \(\sum \frac{L_i-1}{2}\),这个下界不太能取到,吗?考虑把一段长度 \(\ge 3\) 的和一段长度 \(<2\) 进行匹配,贪心即可。
- \(T=\texttt{001/011}\):出现次数。
- \(T=\texttt{010}\):两个 \(\texttt{010}\) 可以配对,剩下一个也可以消掉。
QOJ891 Minimum Spanning Tree
首先考虑到最小生成树其实是非树边对一些树边有 \(\ge\) 的限制。如果我们已知树边的大小顺序,那么非树边会被划分为若干个等价类,每个等价类的限制形如 \(\ge p_i\),是一个树型的限制,可以组合数算出来答案。
现在考虑 dp 化这个过程,倒着做 dp,那么状态 \(f_S\) 代表已经确定了 \(S\) 集合的顺序,剩下部分的答案,考虑转移 \(S \cup \{i\}\),记有 \(c\) 条非树边会被 \(i\) 这条边给限制,记 \(k\) 代表还没有被限制的边的条数,那么有转移:
最后 \(f_0\) 就是答案,时间复杂度 \(O(n2^n)\)。
QOJ1443 Potato Shuffle
套路地,把数分为大于一半和小于一半,那么大数之间的顺序相对确定。我们把小数可以移动的范围用一个区间 \([l_i,r_i]\) 表示其可以移动到第 \(l_i\) 个大数右边,第 \(r_i\) 个大数左边。
显然 \([l_i,r_i]\) 和 \([l_j,r_j]\) 要么相离要么包含,那么所有区间形成了一个树形结构,考虑对这个结构从下往上做 dp,最下层是固定的,方案数是阶乘,再往上就是乘上一个插入方案的组合数再乘上阶乘。把相同的看成不同的最后除以阶乘即可。
最后考虑怎么建出来这棵树,这个很简单,先求出来所有区间,然后按从小到大的区间,找到当前区间位于哪个区间即可,一个 set 可以解决,复杂度 \(O(n \log n)\)。事实上完全不需要建出来这个结构,从大到小插入数就可以了。
P3541 [POI 2010] Monotonicity
考虑设计 dp 为 \(f_i\) 代表第一个序列匹配到了 \(i\),第二个序列最多匹配到 \(f_i\),直接转移就是 \(O(n \log n)\)。
黑割点(cut)
考虑 Alice 输的情况其实是放不下,首先求一下 Alice 放置的最大轮数 \(s\)。
Bob 肯定不会走度数 \(\le k\) 的节点,否则必然会死掉,考虑 Alice 每次会堵掉一个节点。如果 Bob 当前在一个 \(>k\) 的节点上,那么 Alice 可以堵和其相连的所有 \(>k\) 的节点,那么形成了一棵 \(k\) 叉树类的结构?
这个肯定难以处理,但是我们考虑 Alice 输的情况是放不下,也就是说只要有一个 \(>k\) 的节点 Bob 无法走到,Alice 必赢。所以 Bob 的胜利条件是,存在一条从 \(t\) 出发,走 \(s\) 步,每一步都 \(>k\),这个条件先天性要求了 Bob 必须走完所有的度数 \(>k\) 的节点。 从大到小加入节点,如果有分叉路口后面的就一定不行。考虑到如果 \(k\) 合法,那么 \(k/2\) 必定不合法,那么直接根号做就行,好写一点。
哦等等,是不是他妈最多走一步啊。
甜筒的染色树(color)
考虑约束其实是在说蓝色加绿色和黄色加绿色形成连通块。考虑根节点下面额外挂一棵子树的影响,那么这棵子树贡献的方案数是,先有一个到根的连通块选绿色,然后下面全部选绿色或黄色。考虑这个东西正着求,是 \(f_u = \prod f_v + 1\)。考虑设 \(g_{n,i}\) 代表大小为 \(n\),方案数为 \(i\) 的子树的个数,并且有限制钦定根节点是绿色。考虑转移,按顺序枚举根节点下面的所有子树大小。
对无根树算答案,那么有转移:
考虑怎么写代码,再新开一个状态 \(h_{n,k}\) 代表合并了大小为 \(n\) 的,乘起来为 \(k\),算了多重集组合数下面的权值和即可。最后算答案,我们 \(g_{n,k}\) 算的是只有两种颜色的答案。算出来打表即可。
Cone Collection Foundation(cone)
首先考虑一个最简单的构造是直接让 \(S_i \cap S_j = \varnothing\),现在考虑如果这个限制不满足,即如果存在 \(i,j\) 满足 \(S_i \cap S_j = T\),那么先选 $S_i -T $,再选 \(S_j - T\),最后选 \(T\) 即可不合法。
也就是说,我们需要限制使得 \((S_i - T) \cup (S_j - T)\cup H\) 可以使某个人获得冠军。首先考虑 \(H = \varnothing\) 的情况,那么 \(T\) 的大小不能超过 \(6\)。我们把 \(50\) 个数划分为 \(8\) 个块,看成八个点,然后连成一张完全图,那么会连出来 \(\binom{8}{2} = 28\) 条边。
这只是边数的上界,考虑如何构造出一组可行的解。连边的限制形如如果存在边 \((u,v),(u,w)\),则一定存在边 \((v,w)\)。也就是说选择的子图是若干团组成的图。搜一下发现只能搜出来 \(18\) 个的解,有点拉胯。
我们考虑小一点的情况,\((1,2,3,4),(1,2,3,5),(1,2,4,5),(1,3,4,5)\) 其实是合法的,这提供给我们一个思路,一个大小为 \(13\) 的子集,删掉一个数形成 \(13\) 个 \(S_i\),不考虑外界干扰下,它们是合法的。这样能搜出来 \(28\) 个。好像类似构造就可以了。
异或消除(xor)
首先,记 \(L\) 为区间长度,\(h\) 为区间最高位,显然答案为:
因为 \(x\) 必然取不到 \(2^{h+1}\),所以可以对每种最高位分开处理,具体来说,稍微转化,令 \(a'_i=a_i-2^h,S = \bigcup_{a'_i \ge 0} i\),答案为:
进行图论建模,有一条无限长的链,连边 \(i \to i+1\),容量为 \(i\),对于 \(\forall i \in S\),连边 \(s \to i\),容量为 \(1\),\(t\) 位于链上的 \(\infty\)。那么 \(|S| + \min_{x \ge 0}(x - \sum_{i \in S}[a'_i \le x])\) 事实上就是最大流的流量。
考虑往 \(S\) 中加入点 \(x\),如果当前 \(x\) 往 \(x+1\) 流不动了,如果 \(x\) 想走反向边继续流,那么一定会走 \(s \to x \to y(y < x) \to s\) 先回到 \(s\) 然后去 \(z(z >x)\)。然而这样流需要存在 \(s \to z\) 的正向边。如果 \(z\) 还能流得动,肯定不存在这条边,否则 \(z\) 也流不动了,流过去也没用。也就是说,肯定不会退流。
也就是,我们发现了一个惊人的结论,也就是 \(x\) 如果能加入 \(S\) 就加入的贪心是对的!考虑离线版本,对序列做扫描线,维护左端点答案。
从当前右端点往左依次尝试选,选出靠右的集合 \(S\),前缀的后缀的答案一定是和 \(S\) 的交。然后做完了,线段树维护,每次硬把 \(r\) 塞进去即可,然后踢掉一个最前面的不合法位置。时间复杂度 \(O(n \log n)\)。在线版本主席树即可。
QOJ2533 Two Buildings
首先这个括号拆了感觉很难做,考虑什么样的 \((i,j)\) 会成为决策点,发现当且仅当 \(i\) 左边没有比其大的数,\(j\) 右边没有比其大的数,也就是说只有前缀 \(\max\) 和后缀 \(\max\) 会成为决策点。
然后会考虑一个决策单调性类似物,考虑一个前缀 \((i,a_i),(i+1,a_{i+1})\) 和后缀 \((j,a_j),(j+1,a_{j+1})\)。
这个东西满足四边形不等式,直接做分治转移就是 \(O(n \log n)\) 的。
D. 模拟赛
首先对一个位置单独考虑,考虑对于一次对 \(c\) 取 \(\min\),如果它前面有一次 \(\ge c\) 的 chkmax,那么这个操作其实我们并不关心它的值,而只是关心它是否 \(\ge c\)。准确来说这次操作会变成对 \(c\) chkmax。
我们找到最小的一次 chkmin 操作,记为 \(c_{\min}\),经过这次 chkmin 之后原序列都 \(\le c_{\min}\)。那么所有 \(\le c_{\min}\) 的 chkmax 对原序列造成的影响是固定的,而 \(> c_{\min}\) 且在其后面的 chkmax 和原序列无关,所以原序列没有用。
想办法把操作一丢掉,具体来说,每次对 \(x\) chkmax 都可以变成 \(c_i \le x\) 的 chkmax,这里 \(c_i\) 是某次 chkmin 的值。现在的问题是,怎么去重。考虑把操作序列和 \(a_i\) 钦定双射,感觉这并不容易做 dp。
那么加入所有可能的 chkmax 操作,共有 \(O(n^2)\) 种。那么问题变为选择一个 \(S\) 的子集,求生成的序列 \(a_i\) 的种类数。考虑从大往小填,小的一层我们只关心它所有区间的并,然后做一下区间 dp,设 \(f_{l,r,c}\) 代表只用包含在 \([l,r]\) 的所有区间,所有数都 \(\ge c\) 的序列 \(a_i\) 的方案数,时间复杂度 \(O(n^5)\)。
P10685 [COTS 2024] 兔子 Zečevi
首先二分答案 \(t\),那么第 \(i\) 只兔子需要跳到 \(x_i+t\),过程中可以用 \([x_i,x_i+t)\) 来补给,连成一张二分图跑最大流,看最大流是否合法。
二分图区间连边最大流可以贪心,把所有区间按右端点升序排序,每次流某个点会优先选最左边可以选的,然后做完了,时间复杂度 \(O(n \log^2 V)\)。
哦我草,还没有做完,这东西必须要保证对于每一个 \(t' \le t\) 的前缀都是合法的,考虑把左右部点全部拆成单位点权,那么左部点 \(i\) 的第 \(j\) 个单位点连边区间是 \([x_i,x_i+p_i+j)\)。这个时候用 set 就比较困难了,考滤开一棵动态开点线段树,扫描线,在左端点时在线段树上对 \(j\) 的区间做区间加,然后扫到有胡萝卜的时候判断合法性并且把右端点最小的 \(t_i\) 个给清零,时间复杂度 \(O(n \log^2 V)\)。
QOJ12109 讨厌的 Donchik
首先考虑枚举 \(j\),把相邻两个相同的数 \((a,b)\) 提取出来,那么所有跨过 \([j,j+1]\) 的对都不能和 \([i,k]\) 产生相交不包含关系。这个放到平面上是一个动态矩形并类的信息,不太能做。
考虑对于固定的 \((i,k)\),合法的 \(j\) 一定是一段区间 \([l_{i,k},r_{i,k}]\),考虑扫描线,枚举 \(k\),对于 \(l,r\) 分开考虑:如果 \(a_k\) 在区间第一次出现:那么 \(l_{i,k}=r+1\),否则 \(l_{i,k} = l_{i,k-1}\)。而 \(r_{i,k}\) 就是所有最后一次出现某个数的位置中,最小的那一个位置,这两个线段树扫描线维护即可,时间复杂度 \(O(n \log n)\)。
好像需要枚举 \((j,k)\)。
P10055 [CCO 2022] Good Game
考虑 \(\ge 2\) 的连续段可以缩减完,留下来的应该是若干形如 ABABAB 的结构,随便做一下即可。
AT_awtf2024_d Almost Bubble Sort
为什么我没有头猪啊,贪心太难了。
考虑题目要求的限制是两个上升的子序列,我们记第一,二个子序列的下标的集合为 \(T,S\)。那么对于每个 \(i\) 考虑贡献:
- 如果 \(i \in S\):贡献为 \(\sum_{j<i} [j \in S \wedge a_j > a_i]\)。
- 如果 \(i \notin S\):贡献为 \(\sum_{j<i}[j \in S \vee a_j > a_i]\)。
考虑如果 \(|S|=1\) 怎么做,只需要对每个 \(i\) 算出一个增量就可以,选择 \(i\) 的变化量应该是 \(b_i=\sum_{j> i}[a_j>a_i] - \sum_{j<i}[a_j > a_i]\)。考虑 \(|S| \ge 2\) 的复合决策。
考虑 \(|S|=2\),记选择了 \(i,j(i<j)\)。如果 \(a_i < a_j\),那么 \((i,j)\) 不应该产生贡献,多算了一次贡献。反之则少算了一次贡献。首先求出来全局的逆序对 \(inv\),那么选择 \(S\) 的答案就是 \(inv -\binom{|S|}{2} + \sum_{i \in S} b_i + 2\sum_{i,j \in S,i<j}[a_i>a_j]\)。我们发现 \(S\) 的选择一定是增量的,\(k\) 个数的最优解一定由 \(k-1\) 个数的最优解加一个数得到。
进一步,我们可以发现,对于任意 \((i,j)\) 并且 \(a_i>a_j\),不存在 \(i \in S,j \notin S\) 的情况,也就是先选择 \(j\) 一定更优。记 \(val_i = b_i + 2\sum_{j>i}[a_j>a_i]\),那么答案是 \(inv - \binom{|S|}{2} + \sum_{i \in S} val_i\),把 \(val_i\) 从小到大排序,那么时间复杂度 \(O(n \log n)\)。
AT_awtf2024_a Moving Slimes
这也太难了。
考虑 \(k=n\) 的话怎么求答案,一只史莱姆在合并前速度不会改变。那么按合并的时间建一个 set 算答案,每次合并只会对 \(O(1)\) 对史莱姆的合并时间造成影响。
现在考虑 \(k \ne n\),上面那个 set 的做法没啥性质咋办。
首先一定会选一段前缀加一段后缀,把史莱姆的的吸引力放在重心上面,记 \(d_i = suf_i - pre_i\),如果所有 \(d_i\) 都是 \(0\),那么所有史莱姆都在同一个位置。考虑每个 \(d_i\) 需要多久减少到 \(0\)。把史莱姆的移动看成是重心在移动,那么答案的下界就是 \(\frac{\max(d_i)}{k}\),考虑分析上界,终止时需要有 \(a_i = a_{i+1}\)。那么上界和下界相等。那么选择的一定是一段前缀和一段后缀,时间复杂度 \(O(n)\)。
P6881 [JOI 2020 Final] 火灾 / Fire
考虑把位置看作横坐标,时间轴看作纵坐标,那么每次火灾的范围在二维平面是一个三角形。
考虑按纵坐标做扫描线,维护横坐标所有的连续段信息,那么相当于每次移动纵坐标会给峰顶 \(+1\),给谷底 \(-1\),然后要求快速查询区间和。这个感觉不太想摁做,摁做感觉也可以做。
考虑对于每个位置 \(i\),找到右边第一个 \(a_j > a_i\) 的点 \(j\),以及左边第一个 \(a_k > a_i\) 的点 \(k\)。首先考虑 \(i\) 往右边的贡献,应该是一个竖着的梯形,再考虑左边,截完之后应该是一个平行四边形。那么我们只需要做平行四边形加就可以了。
考虑差分,一个平行四边形可以差分成三个贴着下边界的三角形。不妨设三角形的直角在左下角,顶点为 \((x,y)\),权值为 \(w\)。查询区间为 \([1,qx]\),第 \(qy\) 行,那么交的区间为 \([1,qx] \cap [x,x+qy-y]\),对后面一个区间再次差分,交的大小也就是 \(-|[1,qx] \cap [1,x-1] | + |[1,qx] \cap [1, x+qy-y]|\),前面一项当 \(qx \ge x-1\) 时是一个一次函数的形式,可以树状数组维护,后面一项大小等于 \(|[1,qx-qy] \cap [1,x-y]|\),也是一个一次函数的形式。
然后做完了,时间复杂度 \(O(n \log n)\)。
P12547 [UOI 2025] Simple Subsequence
考虑前后缀都非负这个条件是在说什么东西,把放到折线图上面去考虑。前缀非负代表不能碰到 \(y=-1\),后缀非负代表终点是最大值。
现在还维护不了,感觉是缺了个贪心之类的东西。考虑首先全选,然后进行调整,首先需要向上调整前缀和的最小值,然后需要向下调整后缀和的最大值减去终点值,然后做完了,时间复杂度 \(O(n \log n)\)。
AT_arc190_c [ARC190C] Basic Grid Problem with Updates
考虑动态规划的式子是 \(f_{i,j} = (f_{i-1,j} + f_{i,j-1}) A_{i,j}\),每次移动肯定不会全部重跑,考虑维护一手增量。这个东西是不是可以根号重构来着。
维护前缀的 \(f_{i,j}\) 和后缀的 \(g_{i,j}\),那么每次的增量是 \(f_{i,j} \times g_{i,j} \times A_{i,j}\),问题在于如何快速更新 \(f,g\)。由于每次只会移动到相邻格子,考虑每次修改后和修改前只重新计算第 \(i\) 行的 \(f_{i,*}\) 和 \(g_{i,*}\)。因为每次只会动一步,所以这么做是对的,时间复杂度 \(O(nm \sqrt{nm})\)。
P12784 [ICPC 2024 Yokohama R] Beyond the Former Explorer
考虑一个经典的 trick,从某个 \(y=h(h > n/2)\) 切开折线,我们根据切到的次数可以确定终点是在 \(h\) 上方还是在 \(h\) 下方,那么二分出来行的编号,遍历这一行即可。这样通过不了。
对行和列进行交替二分,想办法把遍历一行变为遍历一个区间,考虑会把整个平面分成三个点,这三个点之间有连边,要找一条欧拉路径,这个是容易解决的,那么就做完了。这个挺有意思的。
P16464 [UOI 2026] Game on a Tree
考虑给每个点一个颜色 \(c_u\) 代表必胜必败态,具体来说一个点是 \(0\) 当且仅当相邻节点全部为 \(1\)。
首先考虑修改某个节点 \(u\) 对祖先链上的影响,讨论:
- \(c_u=1\):修改有影响当且仅当 \(fa_u\) 的所有儿子的 \(c_u\) 全部为 \(1\)。
- \(c_u = 0\):修改有影响当且仅当 \(fa_u\) 的所有儿子只有 \(c_u\) 是 \(0\)。
那么修改会影响一段向上的链,考虑怎么维护这个链,发现其实去掉这条链形成的若干子树的根节点颜色全部为 \(1\),因此做重剖维护轻子树,在重链上二分修改的位置即可。
接着考虑子树外的贡献,发现和子树内的贡献维护方式是相同的,直接维护即可,时间复杂度 \(O(n \log^2 n)\)。
平衡子序列(bal)
考虑把括号序列刻画成一张折线图,那么考虑最长的合法子括号序列就是,记折线到达的最低点为 \(-x\),终点高度为 \(y\),那么最长的合法子括号序列就是 \(n+m-2x[x<0]-y[y>0]\)。
那么可以得到等式 \(2k + y + 2x = n+m,y=n-m\),解一下可以得到 \(x_0=m-k,y_0=n-m\)。
也就是说问题变为从 \((0,0)\) 走到 \((n+m,y)\),中途最低点是 \(y=x_0\) 的方案数,这个不是傻逼吗,拿 \((0,0)\) 走到 \((n+m,y)\) 并限制不碰到 \(y=x_0-1\) 的方案数减去从 \((0,0)\) 走到 \((n+m,y)\) 并限制不碰到 \(y=x_0\) 的方案数。
记向上走 \(u\) 步,向下走 \(v\) 步,那么有 \(u-v= y=n-m,u+v=n+m\),也就是 \(u=n,v=m\),反射容斥一下得到答案:
QOJ10970 Array Similarity
考虑维护另一个数列代表相邻两个前缀最大值的下标差,然后求出来这个数列的哈希值。这应该是一个很经典的单侧递归线段树的形式,时间复杂度 \(O(n \log^2 n)\)。
可以离线扫描线,扫 \(l\) 维护 \(r\),前缀 \(\max\) 用单调栈用脚处理,处理查询的时候在单调栈上面二分即可,时间复杂度 \(O(n \log n)\)。
QOJ15697 Phryctoria
考虑缩写串肯定是若干个 \(S\) 的区间 \([l_1,r_1],[l_2,r_2],...,[l_k,r_k]\),中间用 * 隔开。要求 \(T\) 无法匹配,也就是要求 \(T\) 每次连续在原串上走 \([l_1,r_1]\) 的字符,然后跳到 \(l_2\) 的字符,循环,不可以走完。
那么设 \(f_{i,j}\) 代表考虑了 \(S[1:i]\),走了 \(j\) 个区间,最大指针位于 \(f_{i,j}\)。那么考虑转移:
-
\(f_{i,j} \to f_{i+k, j + 1}\):走一个 *,匹配任意长度的 \(S\)。
-
\(\text{find}(f_{i,j},S[i+1:i+k]) \to f_{i+k,j+k}\):这里的 \(\text{find}(i,t)\) 代表找到找到 \(T\) 中第 \(i\) 个下标后 \(t\) 串第一次的出现位置。
最终答案是 \(\min j[f_{n,j} > m]\),直接转移复杂度是 \(O(n^4)\) 的,考虑怎么优化求 \(\text{find}(i,t)\),提前对 \(O(n^2)\) 个子串求出来所有的出现位置,随便预处理一下可以做到 \(O(n^3)\)。
QOJ9312 Random Dungeon
这个题咋这么难。考虑把所有数从大到小排序,策略是每次设定一个阈值 \(t_i\),代表如果抽到的牌是全局前 \(t_i\) 大,那么直接结束并重新设定阈值。那么一定有 \(t_1 \ge t_2 \ge... \ge t_k\)。
那么低于阈值的数都是等价的,因此设 \(f_{i,j}\) 代表还剩 \(i\) 张牌,极长的没有被选择的前缀为 \(j\) 的最大期望收益,直接做是 \(O(n^2)\) 的。
考虑剩下 \(i\) 张牌的时候一定是一个前缀加上一堆等价的牌,那么这个时候最大收益与前面抽的牌无关,设 \(f_i\) 代表还剩下前 \(i\) 大的牌的最大期望,那么有转移:
优化是平凡的,时间复杂度 \(O(n)\)。
QOJ3823 Mountain hike
怎么是张 DAG,考虑设 \(f_{i,j}\) 代表两个点以 \((i,j)\) 为起点,到终点的最小代价,按照拓扑序转移。考虑每次转移都会枚举两个点的邻域,总复杂度 \(O(n^2)\)。
QOJ3083 Bit Operation
首先考虑我们的计数对象是对操作序列,对其做一些转化,转化为每次删掉 \(i\) 或者 \(i+1\) 的数,最后剩下来是 \(1\) 的方案数,
考虑枚举最后剩下的是哪个位置,那么前后缀是独立的问题,设 \(f_i\) 代表前缀 \(i\) 并且保留最后一个数的方案数,那么这个问题此时就和 \(a_i\) 序列无关了。考虑怎么转移这个 \(f_i\),要么随便选前面一个数删掉,贡献是 \(2(i-2)f_{i-1}\),或者选择 \((i-1,i)\) 并把 \(i-1\) 删掉,贡献是 \(f_{i-1}\),那么有递推式 \(f_i = (2i-3)f_{i-1}\),时间复杂度 \(O(n)\)。
QOJ10516 最近公共祖先
首先考虑枚举这个 LCA,然后计算这个点两棵树的子树交集大小,子树内部的贡献可以容斥减掉。把子树拍掉 DFS 序的区间上面,等于求两个序列的两个区间的交集大小。
直接启发式合并,2log 做完了。
P9001 [CEOI 2022] Parking
首先考虑判定,首先 \(n=m\) 是平凡的,然后把初始没有空位并且动不了的给判掉。
考虑所有那些只有一辆车的位置,找到它们配对的另一半。讨论:
- 另一半也只有一辆车:直接把这两个合并即可,不劣。
- 另一半有两辆车,并且在上面:把另一辆车合并过来即可,不劣。
- 另一半有两辆车,并且在下面。记上面的车为 \(a_i\),下面的车为 \(b_i\),那么有一个 \(a_i \to b_i\) 的限制,代表只有当 \(a_i\) 配对完毕才能配对 \(b_i\)。
考虑连出来的图每个点的入边和出边度数 \(\le 2\),也就是连通块的形态只会有链和环,链消完之后会提供空位,如果一个环(无向图上的环)是顺时针或者逆时针单向的,更准确来说是如果环上入度为 \(0\) 的点的个数 \(\le 1\),这个环一定可以只暂时占用一个空位消完,否则一定会占用至少两个空位。那是不是做完了,时间复杂度 \(O(n)\)。
QOJ5504 Flower Garden
考虑 2-sat 连边,最暴力的连边方式是对于 \(x \in [a_i,b_i]\),如果 \(x\) 填 \(0\) 则对于所有 \(y \in [c_i,d_i]\),\(y\) 位置必须填 \(0\),反过来同理。这是一个区间向区间连边的形式,可以线段树优化。
考虑这个 2-sat 实际上不需要处理反过来的限制,因为限制等价,所以我们把 2-sat 拆出来的两个点重新塞回去一个点,选某个点代表某个点选了 F。缩点,那么选择一个强连通分量后就必须选择其在 DAG 上的所有后缀。
首先拓扑序的某个后缀是合法的,如果没有一个强连通分量大小 \(>n\) 的话,肯定可以在某个断点选到 \([n,2n]\) 大小之间的后缀。现在考虑有这样一个大小 \(>n\) 的强连通分量。我们讨论是否选它:
-
选它:由于大小已经 \(>n\),我们选尽可能少的节点,也就是其所有后继节点。
-
不选它:那么限制是其所有前驱节点不能选,由于大小一定 \(<2n\),我们选尽可能多的节点,也就是除了其前驱节点以外的所有节点。
然后就做完了,时间复杂度 \(O(n \log n)\)。
P16365 [OOI 2026] Tasks from Sasha
直接 dp 很烦,如果直接做子树内钦定点的 dp 是 \(O(n^3)\) 的,考虑对 LCA 的限制做一下容斥,具体来说,记 \(T_i\) 代表 \(i\) 的子树集合:
考虑这个限制拆开后的意义是,对每个点选择其自身,权值为 \(1\),或者选择其儿子,权值为 \(-1\),然后对每个 \(S_i\) 都要选择一个其到根的链上节点,然后把权值乘起来。
根据这个考虑做 dp,设 \(f_{u,i}\) 代表做完 \(u\) 的子树,子树的上面有 \(i\) 个关键点的方案数。考虑转移:
-
这个点不进行选择,那么这个点可以不放入某个 \(S_i\),或者放入某个钦定的关键点的 \(S_i\):
\[(i+1) \prod f_{v,i} \to f_{u,i} \] -
这个点进行选择,选择 \([S_i \subseteq T_u]\) 一项:
\[(i+1) \prod f_{v,i} \to f_{u,i-1} \] -
这个点进行选择,选择 \([S_i \subseteq T_v]\) 一项:
\[-(i+1) \frac{f_{v,i+1}}{f_{v,i}} \prod_w f_{w,i} \to f_{u,i} \]
需要注意 \(S = \varnothing\) 需要特殊处理。
那么直接做 dp 就是 \(O(nk)\) 的。考虑优化这个 dp,首先建出来虚树,考虑 \(u\) 的儿子 \(v\) 如何从下面的虚树节点 \(w_{1 \sim k}\) 转移而来,我们发现虚树上的点只会进行第一种转移,那么每个虚树上的点都会贡献一个 \(i+1\) 的系数。
但是这样还是爆的,因为转移三会枚举那些没有任何关键点的子树。考虑到同一个大小的子树的转移三是等价的,所以可以把多个相同大小的子树一起做,那么分析一下就有复杂度 \(O(n + k^2 + n^{0.5}k^{1.5})\)。
感觉这个题很有意思的一点是把子树内的钦定通过容斥变成了对祖先的钦定?
P15952 [ICPC 2018 Jakarta R] Rotating Gears
如果做过黑白树应该会很熟悉这个做法。
考虑如何描述两个点 \(u,v\) 处在同一个连通块,我们记 \(c_u\) 代表 \(u\) 到根节点的删除的节点的个数,那么 \(c_u=c_v\) 则 \(u,v\) 在同一个连通块。
每次进行三操作修改时,我们考虑找到修改点所在的连通块的最顶部节点 \(x\),找到 \(x\) 对应的 DFS 序上的区间 \([l_x,r_x]\),我们考虑如何找到区间内每个和 \(x\) 同一个连通块的点,即 \(c_u=c_x\) 的点。
对 DFS 序建立线段树,那么我们不难观察到,线段树上某个子区间中存在一个点和 \(x\) 处在同一个连通块的一个必要条件是这个子区间的 LCA 和 \(x\) 处在一个连通块。那么我们线段树标记下放的标记 \(c_0\) 就必须要满足 \(c_0 = c_{\text{LCA}}\),这个也就是标记下放的前提,那么每个点的标记信息可以快速维护出来。
为什么修改的时候这么做是对的?因为修改我们找到了连通块的最顶层节点,\(x\) 对应 DFS 序的任意子区间的 LCA 的深度都大于等于 \(x\) 的深度。
那么因此就可以用线段树来维护这个过程,精细实现后可以做到时间复杂度 \(O(n \log n)\)。这个做法应该还可以做一些什么黑白连通块单点改颜色,连通块信息修改,连通块信息维护之类的东西。
P5189 [COCI 2009/2010 #5] ZUMA
这个数据范围考虑做区间 dp,直接设 \(f_{l,r}\) 代表区间 \([l,r]\) 消除完的最小代价。考虑每次 dp 到一个区间 \([l,r]\) 时,枚举 \(x\) 并且保留所有颜色为 \(x\) 的放在最后统一消除,对所有分割开的区间求答案并求和。
这么贪是错的,考虑对这个过程 dp,用辅助数组 \(g_{r,y}\) 代表当前转移到了 \(r\),左端点连续段长度为 \(y\) 的最小代价。那么有转移:
- \(g_{r,y} + f_{r+1,r'}\to g_{r', y}\)。
- \(g_{r,y} \to g_{r+1,y+1} [a_{r+1}=x]\)。
那么直接转移就是 \(O(n^4 k)\) 的。
QOJ7153 XOr
考虑从最高位向低位考虑,假设当前考虑 \(2^h\) 位,那么每个位置都是 \(0/1\),如果 \(1\) 的个数是奇数,就会限制那些左边有奇数个 \(1\) 或者右边有奇数个 \(1\) 的位置不能作为断点。
从高层向底层做,每次看限制之后是否断点数量 \(\ge m-1\) 即可,时间复杂度 \(O(n \log V)\)。
QOJ5059 Plants vs Zombies
从时间小的僵尸开始考虑,那么后面的僵尸等于说有一个起始位置,但是我们考虑可以给它们放回零节点并增加血量,这样每只僵尸独立,但是有一个强制在线类的东西。
这玩意儿他妈不是可以二分吗,做完了,时间复杂度 \(O(n \log D)\)。哦好像在原地直接二分就是对的。。。
QOJ12121 Golf
首先如果 \(a,b\) 加起来是 \(2^k\) 可以搞一个完全二叉树,考虑加起来不是找到 \(2^k \ge a+b\),然后把剩下的部分全部连回完全二叉树的 \(1\) 节点就可以。
现在要卡次数,后面不会了,太难了。
P4689 [Ynoi Easy Round 2016] 这是我自己的发明
以 \(1\) 为根,考虑讨论查询的 \(x,y\) 和当前的 \(rt\) 的祖先后代关系,如果 \(x\) 不是 \(rt\) 的祖先那么 \(x\) 的子树信息就是原本的子树信息,否则是子树补信息。
考虑拍到 DFS 序的区间上面,那么子树补信息和子树信息都可以是一个区间,这个信息感觉直接做维护不了,考虑一些其他的东西。直接莫队是 \(O(n^{7/4})\) 的,但是考虑到 \(cnt_{1,l_1,r_1} \times cnt_{2,l_2,r_2} = (pre_{1,r_1} - pre_{1,l_1-1}) \times (pre_{1,r_2} - pre_{1,l_2-1})\),那么直接做莫队是不是可以做到 \(O(n^{3/2})\)。
T762487 「IXOI R2」想不出来
考虑生成的序列 \(p_i'\) 有何特点,我们把操作刻画成,选择若干个区间,把区间全部置零并可以在除开左右端点的位置填上区间和。限制更具体一点:
- 所有非 \(1\) 的数不能和其他数相邻。
- 所有用 \(1\) 间隔开的段内部数的区间和必须等于区间长度。
首先我们考虑对外层 dp,我们设 \(f_{i,0/1}\) 代表当前到了 \(i\),连续段结尾为 \(0/1\) 的方案数。然后考虑段内部的 dp,设 \(g_{i,j}\) 代表当前总和为 \(i\),还剩下 \(j\) 个位置的权值和,直接转移就是 \(O(n^3)\) 的。
考虑优化,把贡献拆掉,把每个被 \(1\) 间隔开的段分开考虑,我们视作是连续填了 \(p'_i\) 个 \(x_i\),把序列的权值改为所有数的乘积。更准确说,我们用一个单增的序列 \(q_i\) 对 \(p'_i\) 建立单射,那么序列的权值就是 \(\prod x_{q_i}\),对 \(q_i\) 的限制应该是相邻两个数满足差值等于 \(0\) 或者 \(\ge 2\),并且要求单增。特殊地,长度为 \(1\) 并且 \(q_i=i\) 的段可以相邻,那么设 \(f_{i,j,0/1}\) 代表 \(q_i=j\),最后一个段长度是否为 \(1\) 的答案,前缀和优化后就是 \(O(n^2)\) 的。哦,还需要去掉一下 233 之类的东西,需要再加一维代表是否钦定下一位不相同。
情书(quattuor)
很有意思的图论题!
- 结论:对于一张 \((p+q+1)\)-简并图,存在一个顶点集的划分 \((A,B)\),使得 \(G[A]\) 是 \(p\)-简并图,\(G[B]\) 是 \(q\)-简并图。
考虑归纳证明,首先一定能找到一个度数 \(\le p+q+1\) 的节点 \(v\),考虑节点 \(v\) 向 \(G-v\) 划分出来的 \(A,B\) 集合连边总数等于 \(p+q+1\),那么也就是要么向 \(A\) 集合连边的数量 \(\le p\),要么向 \(B\) 集合连边的数量 \(\le q\),哪一边满足就把丢到哪边去。
那么我们首先把 \(5\)-简并图先拆成两张 \(2\)-简并图,然后再拆成两张 \(0\)-简并图和两张 \(1\)-简并图,就是两个独立集和两棵树。记 \(c(V)\) 代表顶点集 \(V\) 对应的连通块个数,我们证明当 \(c(V_3) + c(V_4)\) 最大化时,构造一定合法。
考虑如果 \(V_3\) 有一个 \(\text{deg}_u\ge 3\) 的节点 \(u\),记 \(\lambda_1,\lambda_2,\lambda_3\) 分别代表这个节点向 \(V_1,V_2,V_3\) 三个集合的连边,那么肯定有:
如果 \(\lambda_1 = 0\) 或者 \(\lambda_2=0\),那么可以直接把 \(u\) 节点划分到独立集里面,否则把 \(u\) 节点划分到 \(V_4\) 里面,这样做连通块个数会 \(+2\),那么就证明到了!构造同证明即可,时间复杂度线性,真是太牛了。
P10042 [CCPC 2023 北京市赛] 三染色
用一个 \(h_{i,j}\) 的高度矩阵对模 \(3\) 意义下的 \(a_{i,j}\) 建立映射,具体来说首先有限制 \(h_{i,j}\) 和 \(a_{i,j}\) 模三下同余。那么最终停止的时刻应该是最小值的点到 \((1,1)\) 的曼哈顿距离。对 \(h_{i,j}\) 的限制是相邻位置最多相差 \(1\)。
我们发现,\(h_{i,j}\) 和 \(a_{i,j}\) 建立了双射,归纳构造,假设已经构造了 \(h_{i,j-1},h_{i-1,j}\),那么有 \(|h_{i,j} - h_{i,j-1}| \le 1, |h_{i-1,j} - h_{i,j}| \le 1\),如果有合法解那么 \(h_{i,j}\) 是唯一的。
手玩发现,不合法当且仅当存在如下的矩阵任意旋转,置换后的子矩阵:
考虑做轮廓线 dp,第一问是平凡的,第二问我们不妨设 \(h_{1,1} = a_{1,1}\),那么我们有 dp 状态 \(f_{S,mn,x,d}\) 代表状态 \(S\),之前的最小值为 \(mn\),当前列的第一个数是 \(x\),最小值到 \((1,1)\) 距离为 \(d\) 的方案数。
注意到,我们并不关心 \(mn,x\) 的具体值,而只关心它们的大小关系,那么记录差值 \(v=x-mn\)。我们对 \(d\) 关心其和某个 \(i+j\) 的大小关系,考虑记录 \(d-j\),我们发现 \(<0\) 的部分和 \(=0\) 意义相同,那么状态数就缩减到了 \(O(3^n(n+m)n)\),时间复杂度 \(O(3^n(n+m)n)\)。
P9247 [集训队互测 2018] 完美的队列
考虑对每个询问加入的数刻画这个操作加入的数被完全弹出的时间 \(t_i\),即 \(x\) 在时刻 \([i,t_i]\) 中存在,求出这个后求答案是简单的。完全被弹出,也就是每个位置 \(j\) 都至少加入了 \(a_j\) 个数。
建一棵线段树,每次把操作 \([l,r]\) 拆成 \(O(\log n)\) 个区间挂在线段树上,考虑做线段树分治。
不妨设当前这个节点为 \([L,R]\),那么加入数挂的标记要么在其子树要么在其祖先,在子树的区间总量级是 \(O(n \log n)\) 的,可以暴力在这个节点里面加入。在祖先挂的标记对这个节点是全局的。
现在考虑如何处理这个节点的查询,很明显有 \(t_i\) 随 \(i\) 单增,所以把所有查询双指针处理。初始有一个数组 \(h_j = a_j\),每次加入一个子树内的操作 \([l,r]\) 就做区间 \(h_j\) 减一,如果操作来自父亲则给全局加的标记 \(s\) 加一, 那么弹出的条件就是 \(\max h_j \le s\)。那么时间复杂度就是 \(O(n \log n + m \log^2 n)\)。
P7740 [NOI2021] 机器人游戏
首先考虑 \(n\) 比较小的情况,我们大力容斥,钦定 \(k\) 个起点,那么每个串提供的限制会钦定某些位置必须填什么,更具体来说是给每个位置一个 \(1,2,3\) 的权值,直接做是 \(O(n^2m2^n)\) 的。
现在考虑对 \(n\) 做折半的处理,我们对最右边的合法起点位置 \(p\) 讨论,如果 \(p \le \dfrac{n}{2}\),可以直接用上面的暴力做。否则,那么最大位移最多只有 \(\dfrac{n}{2}\)。那么考虑设 \(f_{i,S}\) 代表做到了第 \(i\) 位,状压 \([p - \dfrac{n}{2},p]\) 是否有起始点。那么直接大力做就是 \(O(nm2^{n/2})\) 的。这个过程还可以 bitset 优化,总时间复杂度 \(O\left (\dfrac{nm2^{n/2}}{\omega} \right )\)。
宝石装置(gem)
妈的,考虑单独对每个点二分,随机一个顺序就是 1log 的。
CF1615F LEGOndary Grandmaster
首先考虑怎么求这个最小时间,考虑把所有奇数位做翻转,那么每次的操作相当于交换相邻的 \(01\),那么总代价就是 \(1\) 的下标的一一匹配的代价。
考虑贡献写出来的样子应该是 \(\sum |x_i - y_i|\),我们设 \(f_{i,j}\) 代表第一个串的第 \(i\) 个字符匹配了第二个串的第 \(j\) 个字符的最小代价和,再维护一个方案数。转移枚举两个串的下一个 \(1\) 的位置,直接转移应该是 \(O(n^4)\) 的。分开转移可以优化到 \(O(n^3)\)。
拆贡献,拆到每条边上面,每条边产生的贡献应该是 \(|pre_{0,i} - pre_{1,i}|\)。把这个记到 dp 里面就是 \(O(n^2)\) 的。哦,这个东西其实可以直接组合数,具体来说,先枚举差值 \(d\),那么一边的方案数形如:
这样也是 \(O(n^2)\) 的,但是据说这个东西可以做到线性。
P14068 [PO Final 2022] 搭塔 / Legobyggartävlingen
直接设 \(f_i\),随便预处理一下可以搞到 \(O(n^2)\)。
P14085 [ICPC 2023 Seoul R] Apricot Seeds
考虑怎么刻画对区间的冒泡排序,考虑我们在分块下的视角,可以看作是从左边塞进来一个数然后再踹出去一个数,那我们考虑对区间也是一样的。
如果这个区间左边和右边的位置足够多,那么左边会加进来前 \(m\) 大的数,然后会弹出去 \(m\) 个数,那么答案是原来的区间和加上左边的前 \(m\) 大再减去左边加上这个区间的前 \(m\) 大。
我们考虑更形式化一点,长度为 \(n\) 的序列排 \(k\) 轮,下标区间 \([1,p]\) 的组成是 \([1,\min(p+k,n)]\) 中前 \(p\) 小的数。那么直接主席树即可。
QOJ13142 Cleaning Robots
考虑树形 dp,设 \(f_{i,0/1}\) 代表考虑完了 \(i\) 的子树,\(i\) 的状态是某条路径端点 / 某条路径中间。考虑转移,\(f_{u,0}\) 的转移是在儿子里面选一个 \(f_{v,0}\),考虑 \(f_{u,1}\) 的限制是选两个点,那么设 \(f_{i,0/1,0/1/2}\) 是不是就可以转移了。
等等,我们发现 \(f_{u,0}\) 的转移不太对,有可能在 \(u\) 的父亲我们没有选它,是不是还要加一维来钦定它的选择。考虑丢掉那些乱七八糟的状态,设 \(f_{u,0/1/2}\) 代表 \(u\) 子树,状态为钦定选 / 某条路径端点 / 某条路径中间。时间复杂度线性。怎么有点红文。
QOJ17140 Odd Rows
首先如果 \(\sum c_i \le n\),我们可以直接构造到上界。考虑如果有两个和大于 \(n\) 的数 \(x,y\),我们可以直接把它们的交集给减掉,也就是减掉 \(x+y-n\)。我们尝试说明一定能构造到上界 \(n - [\sum c_i \equiv 1 \bmod 2]\)。这个很简单,我们每次选两个数 \(x,y\),钦定它们在同一个地方交,也就是给 \(x,y\) 同时减一,如果减完 \(\le n\) 就直接输出构造即可。
原来可以直接大力 dp,设 \(f_{i,j}\) 代表考虑前 \(i\) 列,有 \(j\) 个黑格子是否可行,然后随便转移即可。
P10068 [CCO 2023] Line Town
首先翻转奇数位,然后考虑把所有数按绝对值从大到小排序,那么原题的排序过程可以看作是划分成两个子序列,两个子序列都需要正负交替。可以看作是一个在两边依次填数的过程。
先考虑 C 性质所有数都互不相同,设 \(f_{i,0/1}\) 代表考虑了 \(i\) 个数,左边填的个数是偶数 / 奇数的最小交换次数,每次加入一个数,讨论放在左边还是右边,把贡献提前算了,是一个逆序对状物,直接可以做到 \(O(n \log n)\) 的时间复杂度。
现在我们考虑相同的数,问题是转移的加入顺序不一定对,但是我们考虑到相同的数肯定会是正负交替,枚举左右两边放的个数复杂度就是对的,时间复杂度 \(O(n \log n)\)。
QOJ12602 朱大师与多边形
首先我们考虑如何判定正多边形上面的一个角是不是锐角:对于顶点 \(i\),设其在凸多边形中的相邻顶点为 \(j,k\),则角 \(i\) 为锐角当且仅当不包含 \(i\) 的那条弧的边数不超过 \(X\)。首先 \(k=3\) 只有 \(m=3\) 有解,考虑 \(k \le 2\) 的情况,考虑做钦定然后做二项式反演。下文记 \(X = (n-1)/2\)。
首先考虑 \(k=2\),我们首先枚举一个锐角 \(i\),具体来说枚举和这个锐角相邻的两个顶点 \(j,k\) 的距离 \(d\)(包含端点)。然后考虑过 \(i\) 画一条直径把 \(j\) 到 \(k\) 的 \(d-2\) 个点划分为两个部分,那么钦定两个顶点就是说选择 \(i,j,k\) 并且只选择某一个部分里面的点,那么可以写出和式:
现在考虑 \(i\) 可能在 \(j,k\) 的外面,首先外面有 \(n-d-(d-1)=n+1-2d\) 个点,我们发现选择任意一个点后,在 \(j\) 到 \(k\) 任意选择点都是合法的。那么有和式:
由于有:
经过重新计数,上述 \(S_{2,0}\) 与 \(S_{2,1}\) 的拆分存在重复计数,不能直接相加得到正确的 \(S_2\)。正确的 \(S_2\) 为:
接下来考虑算钦定有一个顶点的情况,那么这个就比较轻松了,同样枚举 \(d\),那么我们发现任意取都是合法的,那么贡献是:
最后把贡献合起来就可以算出来 \(0\) 个锐角的答案了:
其中
时间复杂度 \(O(n + T)\)。一坨屎这个题目。
P17197 [KOI 2026 #2] 删除局部最小值
好像和 UNR 一个叫麦田的题差不太多。
考虑怎么去刻画删除最小值,我们考虑建出笛卡尔树,那么删除一个点当且仅当这个点在笛卡尔树上的儿子全部被删完,一个点的删除时间也就是它的最大深度。
现在的问题是区间保留一棵笛卡尔树,查询最大深度 \(>t\) 的点个数。考虑由于是个排列,那么笛卡尔树肯定是一棵二叉树,考虑区间保留下来的笛卡尔树长啥样,不难发现肯定是一棵原来的子树然后删掉左链底部某个左子树,右链底部某个右子树,换句话说只会有这两棵子树到根链上的节点的最大深度会受到影响。那么我们直接在根链上对 \(t\) 做二分即可,时间复杂度 \(O(n \log n) \sim O(n \log^2 n)\)。
P17019 [ROI 2026 Day1] 泰莫利亚的调查
我们首先考虑题目在说什么,首先我们发现水晶的传送只会走祖先后代链,答案就是两倍总边权减去选择的链的总边权,选择的链需要点不交。
那么我们发现,如果一个点有多个儿子里面有链,肯定会选到儿子边权最大的那一个儿子连接到 \(u\),其余的停在 \(u\) 的儿子。这个感觉可以搞点凸性之类的东西,但是先不考虑。
考虑做反悔贪心,拿一棵线段树维护所有点的答案,每次加入一条链的时候,考虑遍历这条链到根的所有点,然后遍历这些点的所有儿子,剩下的工作是一个线段树区间加。每个点只会被算一次,所以时间复杂度是对的,\(O(n \log n)\)。
AT_abc288_h [ABC288Ex] A Nameless Counting Problem
草这个题我到底做过几遍了。首先我们考虑去去掉升序的限制,给答案除以一个多重集组合数。这个东西算几把呢。由于原题的第二个限制是异或,考虑到两个相同的数异或起来是 \(0\),所以我们设 \(f_i\) 代表 \(i\) 个互不相同的数的方案数,枚举重复元素的对数,那么答案为:
现在考虑求 \(f_i\),首先考虑互不相同如何刻画,考虑设 \(g_L\) 代表长为 \(L\) 的合法序列个数,考虑拿 \(g_L\) 减去不合法的序列得到 \(f_L\)。设有 \(i\) 个出现了奇数次的元素,有 \(j\) 种出现了奇数次的元素,有 \(k\) 种出现了偶数次的元素。那么对于 \((i,j,k)\),满足条件的序列个数是:
其中 \(\text{odd}_{i,j}\) 代表把 \(i\) 个元素划分为 \(j\) 个大小为奇数的集合的方案数,那么就可以做到 \(O(N^3 \log X)\) 了。
P11923 [PA 2025] 砖块收集 / Zbieranie klocków
这个题怎么是傻福题啊。
考虑初始 \(2 \times 2\) 的正方形不能被删除,但这不太唯一,手玩一下发现还有一些阶梯一样的东西也不会被删掉。我们发现一个点只会存在于一个斜向的阶梯里面。
我们考虑把阶梯写作 \(\texttt{1}\),把初始的 \(2 \times 2\) 里面的点写成 \(\texttt{2}\),那么一个 \(\texttt{1}\) 不被删掉就会形如 \(\texttt{2111112}\),对每个斜行开一棵动态开点线段树维护这个东西,后缀的 \(\texttt{21111}\) 和前缀的 \(\texttt{11112}\) 拼起来会有贡献,这个是容易维护的,时间复杂度 \(O(n \log n)\)。

浙公网安备 33010602011771号