7 月做题记录

1 P12152

一个序列是好的当且仅当其可以被划分为 \(m\) 个子段,使得每个子段都完整覆盖 \([1,k]\)。这暗示着 \(n \geq mk\) 答案才非 \(0\)

所以考虑一个关于段的 DP,考虑这个 DP 需要记录什么状态。首先肯定需要 \(i,j,x\),表示目前到了 \(i\),在第 \(j\) 段,目前匹配到了 \(a_x\)。然后你需要刻画这个完整覆盖 \([1,k]\) 的限制,加入一个数时,我们关心的是这个数是不是之前没出现过的新的数。而加入一个和 \(a\) 匹配的数或一个没有匹配的数应该是两个截然不同的转移。

考虑将每个子段按照匹配点划分,得到了若干个以匹配点结尾的段和结尾至多一个没有匹配点的段。每次通过一段进行转移。

具体地,记 \(f_{i,j,x,p,q}\) 表示 \([1,i]\),且 \(i\) 在第 \(j\) 段,\(i\) 恰好匹配了 \(a_x\),目前这段中匹配了 \(a\) 的本质不同数量为 \(p\),其余的数量为 \(q\) 时的答案。注意这里并不直接钦定每个不匹配的数具体是多少,而只钦定其有 \(q\) 种。向下一段转移时,将方案数乘以 \(q!\) 即可。这个状态数是 \(O(n^3)\) 的。

考虑两种转移,分别是加入一段末尾匹配的,或者加入一段末尾没有匹配的并且结束整个段。

考虑加入一段末尾匹配的,根据 \(p\)\(x\) 以及下一次的位置可以确定加入的数是否是 \(p\) 个数中的,但无法判断其是否在 \(q\) 个未匹配的数中出现。考虑分别计算这两种贡献。若钦定其在 \(q\) 个数之中,则要求先在 \(q\) 个数中选一个数把贡献算上,然后再考虑段内每个数的情况。如果钦定其不在 \(q\) 个数内,直接转移就行了。然后可能是需要开多一些 DP 维护这些,细节似乎挺多。

2 CF724F

考虑先把无标号无根树计数通过重心转化成无标号有根树计数。

然后记 \(f_{i,j}\) 表示 \(i\) 个点,除根和叶子外每个点度数都是 \(d\),且根的度数为 \(j\) 时的方案数。转移简单插板即可,复杂度 \(O(n^2d^2)\)

3 CF1534F2

注意不到啊。

建图缩点变为 DAG 是可以做出来的。

然后等价于每一列的第 \(a_i\) 个点要被覆盖,就是选一些列的最上端的点使得每个关键点都存在前驱被选。

然后很深刻的,对于每个关键点,能出发覆盖他的肯定是列上的一个区间,证明显然,但我为什么注意不到???

然后就是若干个区间,要选尽量少的点覆盖所有区间,按 \(r\) 排序贪心就好了。

4 CF1383E

比较简单。

考虑判定一个串合法。

首先要求开头和结尾的 \(0\) 数量不超过原串对应的数量,然后可以视为给定字符串和要判定的字符串开头结尾都是 \(1\)

考虑原串的 \(1\)\(0\) 分为了若干段,每段长度依次为 \(c_1,c_2,\cdots,c_m\)。判定串同理,长度依次为 \(d_1,d_2,\cdots,d_k\),考虑一开始判定串只有一个 \(1\),每次加入 \(d_i\)\(0\) 和一个 \(1\),然后考虑原串匹配到哪。这个东西显然可以贪心,每次选第一个 \(c_j \geq d_i\) 的并跳转到 \(j+1\) 即可。

这个过程其实就是个自动机,所以直接考虑在自动机上 DP,这个自动机边数太多,先把暴力的转移写出来,发现你只需要维护单调栈就可以线性做了。

5 P11921

这是题吗?

首先可以证明答案分母不超过 \(n\),分子不超过 \(l\)

由于只有 \(O(nl)\) 个答案,可以对答案二分。考虑判定答案 \(x\)

\(t_i\) 表示人 \(i\) 的睡觉开始时刻,则要求对于每个人,\([t_i,t_i+x)\) 时间空闲,且每个时刻至少有一个人醒着并空闲。

如果已经知道排列 \(p_1,p_2,\cdots,p_n\) 表示 \(t_{p_1} \leq t_{p_2} \leq \cdots \leq t_{p_n}\),则贪心的对于每个 \(p_i\),应该取 \(\geq p_{i-1}\) 的最小符合条件的时刻,这不难用调整证明出来。具体地,符合条件意味着范围内空闲,且选的这段选完后不存在某个时刻全都满了。

找下一个最早位置可以简单算出。

然后我们声称每一步,找到每一个人的下次开始时刻,则下一个只会取最小值或次小值?这很困难。

然后就得到了一个 \(O(2^nn)\) 的判定了,很厉害。

6 P11947

对于区间 \([l,r]\),必然是全取 \(b\),而前后缀的全取 \(a\)

我们列出 \([l,r]\) 合法的充要条件:

  1. \([l,r]\) 的任意非全部的前后缀和大于等于 \(0\)
  2. \((r,n]\) 的任意前缀和小于等于 \(0\)
  3. \([1,l)\) 的任意后缀和小于等于 \(0\)
  4. \([l,r]\) 的和大于等于 \([1,l)\)\((r,n]\) 的最大子段和。

限制 \(2,3\) 是很容易的,相当于限制只有一部分 \(l,r\) 合法,把不符合的删去即可。

考虑限制 \(1,4\) 大概是什么。当 \(l\) 固定时,只考虑前缀和的限制,有一个 \(x\),要求 \(r \leq x\)。对于限制 \(4\),由于存在负数,区间和没有单调性,所以只考虑 \([l,r]\) 的和大于等于 \([1,l)\) 最大子段和限制了部分 \(r\) 不可行。但事实上,如果存在 \(r_1 < r_2 < r_3 \leq x\) 满足 \(r_1,r_3\) 可行,但 \(r_2\) 不可行,则 \((r_2,r_3]\) 区间和必然为负数,和 \(r_3\) 可行矛盾。所以符合 \([l,r]\) 和大于等于 \([1,l)\) 最大子段和且任意前缀和非负且 \(r\) 可能合法的 \(r\) 是一个区间。这个区间满足任意前缀和非负且和大于等于前面的子段和。

对于 \(r\) 有相对于 \(l\) 的限制。

所以容易求出 \(a_i,b_i,c_i,d_i\),则区间 \([l,r]\) 合法等价于 \(r \in [a_l,b_l]\)\(l \in [c_r,d_r]\)

对于原来的这个询问,考虑离线做扫描线,按照 \(l\) 从大到小,每个 \(r\)\([c_r,d_r]\) 时间段内存活,则对于某个 \(l\),符合条件的即为目前存活的 \(\in [a_l,b_l]\)\(r\)。询问即求 \(l = x\) 的区间历史和。这个很容易维护了。复杂度 \(O(n \log n)\)

7 P11946

8 P13011

考虑点 \(x,y\) 在一条左链上的条件。不妨假设 \(x<y\),则至少要求 \(p_y > p_x\)

然后考虑若 \((x,y)\) 之间存在 \(>p_y\) 的数,则访问到那个位置时必然把 \(x,y\) 分开了,所以要求 \(\forall z \in (x,y)\)\(p_z < p_y\)

此外,找到最靠右的符合 \(p_z > p_x\)\(z < x\)\(z\),要求 \(p_z > p_y\),原因是若 \(p_z \in (p_x,p_y)\),则 \(y,z,x\) 显然形成了一个非左链的结构。

不难验证这个是充要条件。

其实这一堆条件等价于,记 \(r_i\)\(<i\) 的最大的 \(j\) 使得 \(p_j > p_i\),则 \(r_x = r_y\) 即为充要条件。

先考虑单组询问的做法,枚举 \(r_x = i\),不妨假设 \(i \geq 1\),并对 \(i=0\) 单独计算贡献。则我们先将 \([i,y]\) 中的数拉出来,有 \(\dbinom{n}{y-i+1}\) 种,然后 \(p_i\) 必然为区间最大值,\(p_y\) 为次大值,中间的东西随意排,但要求 \(p_x\)\((i+1,x]\) 的前缀最大值,这个方案数显然是 \(\dbinom{y-i-1}{x-i}\times (x-i-1)! \times (y-x-1)!\)。此外,还有 \([i,y]\) 之外的数。所以对于固定的 \(i\),方案数为 \(\dbinom{n}{y-i+1} \times \dbinom{y-i-1}{x-i}\times (x-i-1)! \times (y-x-1)! \times (n-y+i-1)!\),拆开即为 \(\dfrac{n!}{(y-i+1)!(n-y+i-1)!} \times \dfrac{(y-i-1)!}{(x-i)!(y-x-1)!} \times (x-i-1)! \times (y-x-1)! \times (n-y+i-1)!=\dfrac{n!}{(y-i+1)!}\times \dfrac{(y-i-1)!}{x-i}=\dfrac{n!}{(x-i)(y-i)(y-i+1)}\)

即求 \(\sum \limits_{i=1}^{x-1} \dfrac{1}{(x-i)(y-i)(y-i+1)}\)

注意到 \(\dfrac{1}{(y-i)(y-i+1)} = \dfrac{1}{y-i} - \dfrac{1}{y-i+1}\),即求 \(\sum \limits_{i=1}^{x-1} \dfrac{1}{(x-i)(y-i)}\)

裂项,这个式子的 \((y-x)\) 倍为 \(\sum \limits_{i=1}^{x-1} \left(\dfrac{1}{x-i} - \dfrac{1}{y-i}\right)\)

这个直接维护 \(\dfrac{1}{i}\) 前缀和就行了。复杂度 \(O(n_{\max}+\log P)\)

9 CF1037H

考虑直接建 SA,考虑要求是 \(suf_i > suf_x\),且最长公共前缀小于 \(r-i+1\)

考虑最长公共前缀 \(\geq r-i+1\) 的位置,其可以通过枚举给定串的后缀简单计算。于是整个 \([l,r]\) 被拆分为若干部分,每个部分取最小的符合条件的即可。复杂度 \(O(n \log n)\)

10 P11945

考虑扫描线,过程中相当于有一个数轴,支持加入和删除线段,每条线段会与其所在时刻中所有有交的线段连边。

考虑任意时刻,存活的线段按照连通性将数轴分为了若干连续段,对于每个连续段维护其连通块内所有存活线段,加入一条线段只需要合并一些东西,然后这个东西容易颜色段均摊和启发式合并维护。

11 P11948

图是不重要的,先对图边双缩点变成点带权的树。

然后在树上做染色,显然等价于选一条路径,路径上的点递增染色,其余点染离这条链最近的点的颜色。

\(1\) 为根,记 \(f_u\) 表示对于 \(u\) 子树内,假设 \(u\) 为链的一端,结果的最小值。转移大概是 \(f_u = \min \limits_{v} \{f_v + \binom{s_u - s_v}{2}\}\)

显然你需要对于每种根计算,所以考虑换根 DP,换根过程只需要修改两个点的 \(f\) 以及 \(s\),这个转移拆开应该可以直接李超树维护。

12 P4094

二分答案,目标变为判定 \(s[c\cdots c+x-1]\) 是否出现在 \(s[a\cdots b]\) 中。

这等价于是否存在 \(y \in [a,b-x+1]\) 使得 \(\mathrm{LCP}(s[y \cdots n], s[c\cdots n]) \geq x\)

根据 SA 的理论,只需要找到 \(rk_c\) 前后第一个 \(\in [a,b-x+1]\) 的数即可,主席树维护即可。复杂度 \(O(n \log^2 n)\)

13 CF2115C

考虑策略的大致形态。

如果以 \(p\) 概率抽到全体减 \(1\),且最小值不是 \(1\),则必然操作,证明是说如果不合法显然可以和后面调整一下。

另一方面,如果以 \(1-p\) 概率抽到单个减 \(1\),只要不全相等,则必然操作。若全相等,则需要决策。这个就是需要进行 DP 的部分。

具体地,记 \(f_{i,j,k}\) 表示还剩 \(i\) 轮,目前序列有 \(j\)\(k+1\)\(n-j\)\(k\),最终操作成功的概率。这个可以 \(O(1)\) 转移。

在第一次使得全部数相同之前,每次单点减 \(1\) 必然会操作,记这样的操作需要 \(s\) 次,枚举最后一次这样的操作使得操作后全部相同,记为第 \(i\) 次,则相当于是 \(i-1\) 里选 \(s-1\) 个,所以 \(\dbinom{i-1}{s-1}(1-p)^{s}p^{i-s}\),乘以后面的 \(f_{m-i,0,*}\) 求和即可。复杂度 \(O(nmV)\)

14 梦熊模拟赛 T1

对于每个点问其一级邻域求和,则叶子贡献系数为 \(1\),根贡献系数为 \(2\),其余点贡献系数为 \(3\)

然后你可以花 \(n-1\) 次询问求出第一二层的三个点构成的集合,然后询问出哪个是根以及哪两个是深度为 \(2\) 的点,这样你可以把叶子不够的贡献加上来,并且把根的贡献删去然后解方程。次数是卡满的。但据说可以更优。

15 梦熊模拟赛 T2

考虑 \(a_i > b_i\) 的最多选一个。

如果只有 \(a_i < b_i\),视为若干区间 \([a_i,b_i]\),选择的只能是有交区间,线段树维护即可。

将所有点画在平面上,若 \(a_i < b_i\),点为 \((a_i,b_i)\),否则点为 \((b_i,a_i)\)。如果只选 \(a_i < b_i\) 的点,等价于选择一个 \(y=x\) 上的点 \((x,x)\) 的左上角的所有点。如果要选一个 \(a_i > b_i\) 的点,则相当于选择其和其左上所有 \(a_i < b_i\) 的点。

显然我们只需要在过程中保留 \(a_i > b_i\) 的点构成的右下的外围,也就是一个点右下范围有点则忽略,所以你得到了一个 \((b_i,a_i)\) 的点序列,满足 \(b_1<b_2<\cdots< b_k\)\(a_1 < a_2< \cdots<a_k\)

加入一个 \(a_i<b_i\) 的点,等价于对这个点序列做区间加,线段树维护即可。现在唯一的 \(2\)\(\log\) 部分在于加入一个 \(a_i > b_i\) 的点时,要询问其左上角的点数量,这是动态二维数点,直接做不容易做到一个 \(\log\)。考虑加入 \((b_i,a_i)\) 时,若存在某个加入的 \(a_j < b_j\) 使得 \(a_j \in [b_i,a_i]\)\(b_j > a_i\),则这个 \((b_i,a_i)\) 是没有用的,因为你直接取 \((a_i,a_i)\) 左上角所有点即可。所以这个等价于数 \((a_i,a_i)\) 左上角点数,就做到 \(O(n \log n)\) 了。

16 梦熊模拟赛 T3

假设树以 \(1\) 为根。

直接考虑每条边被经过的次数除以 \(2\),也就是这条边从外边往子树内走的数量,记为 \(s_i\)。答案就是 \(\sum 2\times s_i\times w_i\)。考虑一个合法的 \(s_i\) 符合什么要求。

首先是叶子节点和其父亲的边,要求 \(s = 1\)

其次考虑任意一个点 \(u \neq 1\),其儿子与其的边的次数分别为 \(a_1,a_2,\cdots,a_k\)。考虑 \(u\) 和其父亲的边,假设其 \(s=w\)。首先要求 \(w \leq (\sum a_i) + 1\),因为显然最多只能进入 \(\sum a_i\) 加上 \(u\) 这个点本身进出一次。此外,还有 \(w\) 的下界要求。若 \(\max a_i \leq \dfrac{(\sum a_i) + 1}{2}\),则只有 \(w \geq 1\) 的限制,原因是你考虑类似那个经典问题叫做选取树的重心然后两两匹配,不难发现这个是等价的过程。如果 \(\max a_i > \dfrac{(\sum a_i) + 1}{2}\),即存在绝对众数,那么 \(w\) 大于等于绝对众数减去其他数的和。不难证明 \(w\) 在这两个范围之间均合法,原因是你可以一步步调整过去。

考虑 DP,\(f_{i,j}\) 表示考虑 \(i\) 子树,钦定 \(i\) 和父亲边的 \(s=j\),仅计算子树内的边的最小贡献和。

我们可以归纳证明 \(f_{i,j}\) 关于 \(j\) 下凸。

具体来说,考虑遍历 \(i\) 的所有儿子后,根据归纳假设,其所有儿子的 \(f\) 均下凸,先令 \(f_{s,j} \gets f_{s,j} + 2\times j \times w_{i,s}\),表示加入 \((i,s)\) 的这条边的贡献。显然 \(f\) 仍然有凸性。考虑令每个儿子和 \(i\) 的边的 \(s\) 为其 \(f_{i,j}\) 取最小时的 \(j\),则 \(f_{i,\sum s + 1}\) 已经确定。对于 \(j > \sum s + 1\)\(f_{i,j}\),显然就是每个儿子的凸包的上升段做闵可夫斯基和,所以也上凸。对于 \(j < \sum s + 1\),如果目前的 \(s\) 不存在绝对众数,则所有 \(f_{i,j}=f_{i,\sum s + 1}\),否则每次 \(j\) 减少时,令绝对众数的 \(s\)\(1\),或令非绝对众数部分的某个 \(s\)\(1\),这个显然就是把非绝对众数部分的下降部分和绝对众数的下降翻转部分做闵可夫斯基和,所以 \(f\) 是凸的。

整个过程可以直接平衡树维护之,大概就是你只需要支持将凸包的谷底部分分裂出来,然后翻转,启发式合并即可。

17 P11949

18 梦熊模拟赛 T1

考虑连边 \((x_i,y_i,z_i)\),每个连通块独立,单独考虑答案。

每个连通块取出编号最小的点 \(u\),计算其到其余每个点的异或距离 \(d_j\),要求 \(a_u \oplus d_j \in [l_j,r_j]\),拆成两个限制,分别是 \(a_u \oplus d_j \geq l_j\)\(a_u \oplus d_j \leq r_j\),枚举异或结果和范围限制的 LCP 可以得到若干个区间限制,排序后差分可以做到 \(O(n \log^2 n)\)

进一步,考虑在 Trie 上维护这个过程,依次考虑每个 \(j\),要求其只能在某些子树内,维护动态开点 01-Trie 即可做到 \(O(n \log n)\)

19 梦熊模拟赛 T2

考虑一个 he 之前若不是 hi,则其只会每次往前加一个 s

先对原字符串进行一次所述的操作,考虑将序列分段,分别是单个字符,he,形如 hihihihe 与形如 hihihishe,询问只需要找到其在哪一段即可。

注意到 he 段的长度变化是每次加 \(1\),单个字符则不变,所以容易考虑。

对于后面两种,考虑其长度增长量,前面关于长度线性个位置可以暴力更新,因为总长是线性的。而后面的增长量是固定的。离线按照 \(k\) 扫描线,维护序列 \(a,b\),支持单点修改以及所有 \(a_i \gets a_i + b_i\),以及对 \(a\) 线段树二分,直接维护即可。复杂度 \(O(n \log n)\)

20 梦熊模拟赛 T3

考虑按照 \(x\) 从右到左,对于 \(x=k\) 上的每个 \(1\),在其左侧操作一次,即可将 \(x=k\) 清空。

视为在最左侧存在一条竖线,初始所有 \(1\) 都向左投影到了若干个点。则最终这条竖线上的结果是所有投影的异或。

根据题意,这个结果应该和某个点单独出发投影到的形态相同。考虑这条竖线上最下的和最上的 \(1\),就可以唯一对应原来的起始点。

刻画一个点向左投影的形态,假如 \(x\) 轴之间距离相差 \(k\),则可以发现对应位置 \(y\) 的结果就是 \(\dbinom{k}{y} \bmod 2\)。根据 Lucas 定理,这个结果等于 \(1\) 当且仅当二进制下 \(y \subseteq k\)。所以可以在 \(O(n)\) 的复杂度内判定这条竖线上某个位置的值。

如果能找到最终靠左的竖线上的某个 \(1\),则可以倍增找到最下和最上的 \(1\)

考虑如何找到某个 \(1\)

将网格三染色,则每次选择的三个位置颜色均不同。不妨假设初始点为 \(0\),可以发现每次操作,\(0,1,2\) 三个数的 \(1\) 数量奇偶性都发生了变化。所以在最终的左侧竖线上,按照 \(\bmod 3\) 分类,必然有一类的 \(1\) 数量是奇数。考虑找到这一类中的某个 \(1\)

考虑分治,目前区间 \([l,r]\),要求其中等价类的 \(1\) 数量为奇数,考虑取出 \(mid\),则 \([l,mid]\)\((mid,r]\) 中必然存在 \(1\) 数量为奇数的一侧,若能确定是哪一侧,递归进去即可。

问题变为给定 \(l,r,k\),判定 \([l,r]\) 中,\(\bmod 3 = k\)\(1\) 的数量的奇偶性。

显然 \(1\) 数量奇偶性等于每个起点的奇偶性异或。对于每个起点,相当于询问 \(x \in [1,r]\) 中,二进制下是 \(y\) 的子集,且 \(\bmod 3 = k\) 的数的数量,数位 DP 即可。

21 ARC201D

考虑匹配的过程大概是怎么样的。

考虑存在一个分界点,左侧匹配两个数和小于 \(m\),右侧两个数和大于 \(m\)。则我们可以证明左侧右侧必然都是小和大匹配,画在数轴上就是一堆两两包含的区间。证明可以考虑调整。

直接枚举这个分界位置可以做到 \(O(n^2)\)。进一步,考虑这个分界点越向左越优,因为左侧的匹配肯定能更小。但是此时右侧不一定符合和大于等于 \(m\) 的限制。所以二分这个分界点即可。

22 梦熊模拟赛 T1

考虑点分治,对于分治重心,只需要 DP 出每个点到重心的信息,就可以 \(O(k)\) 支持合并了。复杂度 \(O(nk^2\log n+qk)\)。可以通过。

另外,直接从下往上 DP 而不是枚举第一条边的权值即可做到 \(O(nk \log n + qk)\)

23 梦熊模拟赛 T2

对于冒泡排序,考虑把序列转化成 \(01\),根据每次操作是把每段最后一个数移动到下一段开头,可以看出答案是第一个 \(1\) 之后的 \(0\) 的段数,也就是序列中相邻 \(10\) 的数量。

枚举 \(i\) 表示第一个 \(1\) 的位置,也就是这个 \(01\)\(1\) 的分界点,然后枚举 \(j\),要求 \(p_j \geq p_i\)\(p_{j+1} < p_i\)

这个东西直接算就是 \(O(n^2)\) 的,很容易看出是一个二维偏序结构,即可做到 \(O(n \log n)\)

24 梦熊模拟赛 T3

这个题很高明。

考虑把原树变成左儿子右兄弟的儿叉结构,每个点的 \(a\) 数组存其某个儿子,其 \(fa\) 数组存其兄弟。这个东西是很容易处理出来的。具体来说,依次考虑每个点 \(i\),设 \(x\) 为其父亲,则 \(fa_i \gets a_x\)\(a_x \gets i\)

在这个结构上做 DFS,过程是对于每个点,若其存在儿子,并记录其 DFS 序,则向儿子方向走,否则若其存在兄弟,向其兄弟走。若都没有,回溯至其父亲。这个 DFS 序是在走完儿子方向后存到 \(a\) 中的,所以看着比较有道理。

但是问题是,回溯时求不了父亲,以及重复经过一个点时,虽然其儿子被设为了 DFN,但是无法分辨儿子和 DFN。

考虑上述初始化过程中,如果初始有 \(a_x = x\),则每个点的最后一个儿子本应没有右兄弟,但其兄弟恰好就是其父亲本身。

于是考虑把过程改一下,每次如果有儿子,向那边走并把 \(a\) 清零。一个点的 \(a\) 若为 \(0\),则加入 DFS 序。这样你求出的是 DFS 序的逆序,最终用 \(fa\) 还原一次即可。

25 CF2066D2

考察一个序列合法,当且仅当 \(n\) 的出现次数恰好为 \(c\),且对于任意 \(1 \leq i \leq m\)\(\sum \limits_{j=1}^{i-1}[a_j > a_i] < c\)

直接判定这个是很难的,考虑其等价条件:记 \(cnt_i\)\(i\) 的出现次数,要求 \(\forall 1 \leq i \leq n\)\(i\) 在序列中最后一次出现位置小于等于 \(\left(\sum \limits_{j=1}^{i-1} cnt_j\right) + c\),证明归纳即可。

有了这个结论后,考虑从 \(1\)\(n\) 依次插入数,记 \(f_{i,j}\) 表示插入了 \([1,i]\),目前 \(\sum cnt = j\) 的方案数,转移显然,复杂度 \(O(nmc)\)

26 CF2124F2

这咋会?

考虑这个序列分段的形态,大概需要分成两种,一种是一段为 \(1,2,3,\cdots,x\),为了不重不漏地计数,要求下一个不是 \(x+1\)。另一种是 \(a,a+1,\cdots,b,1,2,\cdots,a-1\),此时对下一个数没有任何要求。

直接设计一个一段段的 DP 就可以做到多项式复杂度,足以通过 F1。但是要做到 \(O(n^2)\) 还需要不少手法。

由于第一种段的存在必须依赖于记录最后一个数,所以状态上不太能低于 \(O(n^2)\)。然而一段段进行 DP 很难进行 \(O(1)\) 的转移,考虑一个个数进行 DP。

考虑从后往前加数,\(f_{i,j}\) 表示填了 \([i,n]\),要求 \(a_i = j\) 的方案数。

考虑转移是怎么样的,如果 \(j=1\),直接枚举这一段结尾并要求下一个数不等于结尾加 \(1\),这可以通过对每个 \(i\) 记录 \(\sum f_{i,j}\) 直接计算得到。

另一方面,若 \(j>1\),则相当于是选一段 \(j\) 开头的上升段,然后从 \(1\) 选到这个数,然后考虑之后的。

这个东西很难直接转移,考虑用辅助数组进行转移。考虑你这个转移的形式就是枚举一个 \(x\),要求 \([i,x]\) 能填入 \(j\) 开头的这段,然后要求 \([x+1,x+j-1]\) 能填入 \([1,j)\),转移系数是 \(\sum f_{x+j,k}\)。所以考虑记 \(g_{i,j}\) 为,枚举一个 \(x\geq i\),要求 \([x+1,x+j-1]\) 能填入 \([1,j)\)\(\sum f_{x+j,k}\) 的和。考虑 \(f_{i,j}\),其首先是 \(g_{i+1,j}\),然后找到最后一个 \(x\),减去 \(g_{x+1,j}\)。于是做到了 \(O(n^2)\)

27 UNR D1T1

真难。

猜测应该是找到一个重心,然后两侧分别取数。但是这个不对,原因是你的重心如果是一个二度点,那么你在取的过程中,就会在中间这条链上不符合要求。

考虑找到一个度数至少为 \(3\) 的,尽量平分树的点。考虑将树分为其重儿子和非重儿子部分。构造过程中,时刻保证非重子树内点数大于等于重子树内点数,且等于其或其 \(+2\),这样每次直接构造,放不下去就爆了。对于非重子树,要优先取其两个儿子,这样才能保证过程中不会有一条边断开导致条件不符合。具体证明等会补。

28 UNR D1T2

\(a,b\) 合在一起排序,将一个匹配视作一个区间,不难看出存在最优解使得任意两个区间要么不交要么包含。

有一个很厉害的套路,我没见过。大概是说,我们将所有数分为若干组,分组的方式是,第一个数组的编号为 \(1\),对于每个数,若其与上一个属于不同原数组,则编号与上一个相同。否则若同时属于 \(a\),则编号为上一个加 \(1\),同时属于 \(b\) 则减 \(1\)

不难观察出每一组相邻的都属于不同原数组,我们还可以证明,匹配必然在同组之内。原因是考虑比如有一个 \(a\) 和上面的某一组的 \(b\) 匹配,则这一段内 \(a\)\(b\) 多。由于段内匹配只能包含于这个区间,所以必然会多出来某个 \(a\),将这个 \(a\) 替换匹配即可调整成更优结果。

问题变为对每一组做,然后合并。

对于每一组,问题等价于,你有一个序列 \(a\),你要对于每个 \(k\),在 \(a\) 中选取 \(k\) 个位置,使得任意两个位置不相邻,最小化权值和。这个可以被建模为流量为 \(k\) 时的最小费用流,所以是凸的。一个做法是分治闵可夫斯基和,大概是记 \(f_{l,r,0/1,0/1}(k)\) 表示区间 \([l,r]\)\(l,r\) 选或没选,选了 \(k\) 个的最小花费,合并做 \((\min,+)\) 卷积即可。

不过有一个简单做法,是 P3620 的反悔贪心做法。大概是你考虑维护若干 \(10101\) 的连续段,每次你可以选择将一个 \(000\) 中间的 \(0\) 改为 \(1\),或者将一个 \(0101010\) 改成 \(1010101\),这个过程可以使用链表和堆维护。

最后每段合并,根据上述凸性,直接闵可夫斯基和即可。

29 CF2124G

怪题。

显然 \(i\) 是前缀最小值,\(j\) 是后缀最大值。

然后你考虑 \(x=0\) 怎么做。你可以枚举 \(i\),然后把 \((i,a_i)\) 画在二维平面上,很容易看出你只需要求出 \(i\) 到下一个前缀 \(\min\) 之间的这一段的前缀 \(\min\),枚举 \(a_i\) 加到了哪个位置,就可以转化成 \(O(n)\) 个有效对 \((i,j)\) 计算答案,这个很容易做的。

但是 \(x\) 的限制很难受,因为你 \(a_i\) 加到两个后面的前缀 \(\min\) 之间时,会有很多数。但这个题值域是线性的,所以你直接枚举 \(a_i\) 加成了什么,显然加到与上一个前缀 \(\min\) 相等时就不需要加了,所以还是 \(O(n)\) 个有效对,然后做完了。

30 CF2124H

好题。

考虑一个序列 \(b\) 合法,当且仅当任意两个 \([b_i,i]\) 区间要么不交要么包含,显然是必要条件,直接归纳即可得到其也为充分条件。

所有区间的右端点是连续的不同整数,这是一个很好的性质。这意味着,所有有交区间的开头必然满足 \(b_x=x\)

考虑以此进行区间 DP,记 \(f_{i,j}\) 表示在 \([i,j]\) 中选数,钦定 \(b_{a_i}=a_i\),也就是说 \(a_i\) 是这样的一个连续段开头,最终的序列最长多长。这里不考虑 \(a_i\) 以前的限制,即默认 \(b_1,b_2,\cdots,b_{a_i-1}\) 已经填满并符合条件。

考虑转移。首先有 \(f_{i,j} \gets f_{i,j-1}\),然后考虑选取 \(a_j\)。若 \(a_j < a_i\),则必然不能转移,因为限制了 \(i\) 是开头。\(a_j = a_i\) 时,直接取,\(f_{i,j} \gets f_{i,j-1}+1\)

考虑 \(a_j > a_i\),此时会有一个区间左端点为 \(a_j\)。所以会存在某个 \(i < x \leq j\) 使得 \(a_x = a_j\),然后 \(x\) 作为段开头满足 \(b_{a_x}=a_x\),转移的值应该是 \(f_{x,j}\)。考虑这样的一个 \(x\) 需要符合的条件。除了 \(a_x = a_j\) 外,要求 \(f_{i,x-1} \geq a_x - 1\),这样你才能使其成为第 \(a_x\) 个数。显然这样的 \(x\) 越小越好,所以只需要在转移中维护最小的 \(f_{i,x-1} \geq a_x - 1\)\(a_x = a_j\) 的位置即可。复杂度 \(O(n^2)\)

31 核桃模拟赛 T1

考虑序列问题怎么做。

\(h\)\(w\) 的最高位 \(1\),如果两个数 \(x,y\) 在之前就有不同,则必然可以被选入一个集合。所以考虑按照这个分类,每个类算答案取 \(\max\)

每一类每个集合最多两个数,这是显然的,所以等价于 \(a \oplus b \geq w\) 连边,求二分图最大匹配。

这个东西直接考虑还是很难。考虑从高到低建 Trie,然后是本题最厉害的部分。考虑对于左儿子内的每个数 \(x\),将其删去并加入 \(x \oplus w\),这样你选的匹配相当于要求 LCA 处权值为一个东西,这个你考虑相当于是每个位如果权值是要求的,可以匹配两棵子树内的点,这个过程可以直接合并!所以在 Trie 上维护这个即可。

树上问题直接 Trie 合并即可。

32 梦熊模拟赛 T1

考虑答案是本质不同个数的平方的期望减期望的平方。

期望很容易计算,拆贡献即可。

平方的期望根据 \(x^2 = \sum \limits_{i=1}^{x} \sum \limits_{j=1}^{x} 1\) 可以变为选两个数产生贡献的形式。

直接枚举两个位置即可做到 \(O(n^6)\)。瓶颈在于里面要做一个反射容斥状物。

假设两个点分别是 \((a,b)\)\((c,d)\),里面的容斥只和 \(c-a\)\(b-d\) 有关,对相同等价类做即可。

场上并没有注意到这个,写了另一种做法,但是没写完。大概是你考虑对于两个点 \((a,b)\)\((c,d)\),要求路径同时经过他们,则必然有且仅有两个中的一个,使得路径先从原点到这个点,然后到另一个点并且不回到这个点。所以钦定这个东西进行计数,维护一些额外信息,也可以做到 \(O(n^4)\)

33 梦熊模拟赛 T2

考虑静态问题能怎么做。我们希望得到一个便于刻画的形态。

这个操作等价于,每次将 \((x_i,m]\)\(2\),然后全局减 \(1\),与 \(0\)\(\max\)

维护一个堆,每次操作时加入两个 \(m-x_i\),则堆中的数表示了目前的有效的后缀加的位置。全局减 \(1\) 时,目前进行过最大的那段后缀加由于减 \(1\) 被撤销了,所以删去堆中最大的数即可。最终的 \(\sum v\) 即为堆中所有数的和。

考虑从另外一个角度刻画堆的加入与删除。我们并不要求每次删去最大的,而是任意删一个,并希望最终保留的数和最小。

问题变为:有 \(n\) 个数 \(x_1,x_2,\cdots,x_n\),我们会从前往后依次考虑每个 \(x_i\),并添加两个 \(m - x_i\),删去集合中任意一个数。需要求最终总和的最小值。修改则是对某个 \(x_i\) 进行单点修改。

对此,建立费用流模型,每个 \(i\) 有边 \((S,i,2,m-x_i)\)\((i,T,1,0)\) 以及 \((i,i+1,+\infty,0)\)。则你要做的就是修改一条 \((S,i)\) 的费用,以及查询最大费用最大流。

由于 \((S,i)\) 容量为 \(2\),可以直接退流后线段树模拟费用流。

34 神秘云斗题

考虑集合大小差不超过 \(1\) 怎么做。维护 sum-hash,每次相减即可确定差的那个数的权值或者确定不存在。

集合大小差为 \(2\) 时,二进制分组,对于每一位,将这一位是 \(0\)\(1\) 分别做差为 \(1\) 的即可。

35 P10627

考虑一个位置 \(i\)\(i+1\),在这个位置的所有决策根据时间顺序,必然是一段后缀全是被堵住的,前面是什么是需要考虑的。注意到,前面必然是先全向左后全向右,或者先全向右后全向左。证明是,你发现你只关注向左和向右的最后一个时刻,所以不是这个形态必然可以调整到更优。

针对这个结论,可以写一个从前往后的 DP,你只关心到 \(i\) 这个位置,先左还是先右,以及左右的数量。状态数是 \(O(n^2)\) 的,直接转移可以得到 \(O(n^3)\)。这个过程大概是写出来观察一下转移形式就可以优化到平方。

36 梦熊模拟赛 T1

平方是容易的,显然操作最终只会变成区间 \(\gcd\)。你需要拆分成若干个区间使得每段 \(\gcd\) 都等于整个区间,这个显然是每次找到左边最短的符合条件的区间并扩展即可。这个过程显然可以倍增做到两个 \(\log\)

37 梦熊模拟赛 T2

手玩一下这个过程,可以发现你只关心左链,然后每个点的移动过程是,你需要考虑其到父亲所在的左链怎么移动。

把这个形式总结出来就是你要动态维护这个树的 DFS 序的某个位值,这个直接平衡树维护即可。

38 UNR D2T1

不妨钦定要考虑的 \(i<j\),发现仅需要考虑 \(p_i\) 为前缀最大值,并且 \(p_j\) 为前缀次大或最大值。

根据这个,不妨考虑按照前缀最大值进行 DP,然后你可以写一个 \(f_{i,j}\) 表示 \([1,i]\),且 \(p_i=j\) 为目前最大值,这个可以直接做到三方,优化一下就是平方的。

39 QOJ2352

根据下发文件,由于数据随机生成,最短路长度大概在 \(1000\) 左右。为了确定下一次走的方向,你需要记录一个 \([0,2]\) 之间的数表示走的方向,不用记录四个数原因是你已经确定不会从过来的方向回去。

直接用 \(2\) bit 记一个值域为 \([0,2]\) 的数需要 \(2000\) bit,显然无法接受。

观察一下可以知道,并不是每次移动都需要记 \([0,2]\) 的三个数,如果这次只能向一个方向走,什么都不用记。如果能向两个方向走,用 \(1\) bit,如果能向三个方向走,用 \(2\) bit。对这个东西跑最短路就能符合限制。

40 QOJ1192

考虑建图,每个点向其不满足条件的方向连一条边,我们得到了一棵内向基环树。

注意到一个点若至少两次通过了满足条件的边,则必然不停机。为了求出距离,问题转化为每次给一个点 \(u\) 和参数 \(x\),问找到下一个使得条件成立的点,或者若不存在则判定其停机。

由于图形态是内向基环树,在环上和根向树上分别维护一下即可。

41 QOJ1197

很厉害的题,学到不少。

对于若干个 \(01\) 变量 \(x_1,x_2,\cdots,x_n\),若花费形式为 \(\sum v_ix_{a_i} \overline{x_{b_i}} + \sum \limits_{i=1}^n c_i\overline{x_i} + \sum \limits_{i=1}^n d_i x_i\),则可以最小割求花费。具体地,建立左侧右侧各 \(n\) 个点,连接 \((S,i,c_i)\)\((i',T,d_i)\) 以及 \((i,i',+\infty)\),割 \((S,i)\) 表示 \(x_i=0\)\((i',T)\) 表示 \(x_i=1\)。对于限制当 \(x_a=1\)\(x_b=0\) 时,花费 \(v\),则连边 \((a,b',v)\),表示若没有割 \((S,a)\),即 \(x_a=1\),且没有割 \((b',T)\),即 \(x_{b}=0\) 时,需要花 \(v\) 的代价割掉 \((a,b')\) 这条边。求解最小割即可解决原问题。

对于原问题,先分析问题的形式。由于覆盖白后不能覆盖黑,所以存在最优解使得先覆盖黑后覆盖白。

对每个点 \((i,j)\) 定义四个值,分别为 \(br_{i,j},bc_{i,j},wr_{i,j},wc_{i,j}\),分别表示这个点是否被黑横向,纵向,白横向,纵向覆盖,这里的横纵都是用至少两个格子覆盖的。这样的好处是可以直接判定一个格子是否需要被单独染成黑或白,以及可以用值相乘计算 \(ax+b\) 的贡献。

你把这个贡献形式写出来会发现,第一个问题是,式子中存在 \(br_{i,j}bc_{i,j}\) 这种同侧相乘的形式,解决方法是你手动把其中某个取反,然后你发现得到的都是两侧的式子。

另一个问题是,在考虑一个格子是否需要被单独染白时,限制是其被 \(br\)\(bc\) 过,且其本身要求是白的,且其没有被 \(wr\)\(wc\) 过,你发现有一个三项相乘的形式,这不好直接刻画。注意到一个点若被黑色纵向覆盖,则存在最优解使得其没有再次被白色纵向覆盖,这是因为你还不如之前就把纵向的拆成两部分。这样你就可以把其中一项扔掉,变成两项的形式,然后跑最大流即可。

42 AT_ACL1_F

考虑操作后的序列中,一段前缀和后缀是操作过程中移动过来的,中间的数都保持不变。

枚举保持不变的 \(b\) 中的区间 \([l,r]\)。显然每个位置最多进行一次操作,所以操作的次数可以被 \([l,r]\) 唯一确定,目标变成判定最终是否可能恰好保留了 \([l,r]\) 中的所有数。

\(a\) 中每种数 \(x\) 根据在 \(b\)\([l,r]\) 的哪侧分别出现了几次划分为 LLL,LLR,LMR 等情况,分别表示三个都出现在 \(l\) 左侧,两个在左侧一个在右侧,一个在左侧一个在中间一个在右侧等。

考虑到我们的操作是针对同一种数的,也就是说不同数之间几乎是独立的。但实则不完全独立,原因是需要考虑中间的数向左和向右的操作的顺序。

本质上来说,我们希望构建有向图 \(l-1\rightarrow l-2\rightarrow\cdots \rightarrow 1\)\(r+1\rightarrow r+2 \rightarrow \cdots \rightarrow n\) 的一个拓扑序,使其符合一些额外的条件,考虑探索额外的条件是什么。

分类讨论上述的若干种情况,发现除了 LLR,LRR 和 LMR 外,其余的情况都可以唯一确定操作的顺序和保留在 \([l,r]\) 中的数的位置,而这三种情况都有两种可能的操作。

考虑 LLR 和 LRR,由于中间并不会保留数,所以与其余的数相对独立,限制只有一个左侧比右侧先或后的条件,直接在图上连边即可。

对于 LMR,有两种操作方式,并且在中间保留的可能分别是左侧和右侧的数,这个就相对来说有些困难了。分析原图的性质。这是两条链,为了存在合法拓扑序,最终的图必然没有环。而注意到这两条链形态很特殊,所有非链边都是在两条链之间连的,所以一个环只有可能恰好包含两条非链边。那么直接考虑一个 LMR 和另一种数之间的限制,限制可能是不能构成环,也有可能是在保留的区间内要求相对顺序,总而言之可以建出一个 2-SAT 模型,问题得到解决。

43 P8334

考虑对于每个 \(x\) 计算最小值大于等于 \(x\) 的概率,求和即为期望。

对于给定的 \(x\),将 \(<x\) 的点称为黑点,反之为白,则希望对于所有 \(u,v\),计算 \(u\) DFS 到 \(v\) 不经过黑点的概率。

这等价于,对于每个点 \(u\),求 \(u\) 出发向子树内 DFS,不经过黑点,期望经过的点的数量。

\(f_u\) 为这个答案,转移形如 \(f_u = 1 + \sum \limits_{v} \dfrac{f_v}{c_u+a_v}\)

对于扫描 \(x\) 的过程,相当于 \(O(n)\) 个单点修改 \(c,v\),求 \(\sum f_u\)

由于 \(a_v \in \{0,1\}\),把 DDP 形式写出来后全局平衡二叉树维护即可。

44 CF1651E

考虑左右两边选两个区间内的点,每个点度数不超过 \(2\),图由若干环和链构成。

对于这个图,求最大匹配是容易的。环的贡献是环长除以 \(2\),链的贡献是链长除以 \(2\) 上取整。

直接把问题拆贡献变成,每条链和每个环贡献多少次,很容易做到 \(O(n^2)\)

本质上,这个题是以一种特殊的方式刻画最大匹配,其原因是每个点度数小于等于 \(2\) 的图有特殊形态。后面的拆贡献则是比较经典的过程。

45 CF1730E

考虑枚举最大值位置 \(a_i\) 和最小值 \(x | a_i\),只需要找到左右两侧第一个 \(x\) 出现的位置即可统计答案。复杂度 \(O(nd(V))\)

本质上,这个题的过程是,我们希望将不同区间之间联系起来,所以钦定了最大值的位置。最小值和最大值并不在所有情况下都类似,这个题就不能枚举最小值,否则复杂度并不正确。

46 CF1792F1

这个限制非常紧,具体来说其对于每个点集都有要求,不妨先考虑如何判定一个图符合条件。

首先,取特殊的 \(S=V\),则要求整个图通过黑边或白边连通,但不能同时连通。不妨设黑边连通,取出所有白色连通块,发现如果一个 \(S\) 包含了不同连通块内的点,则其必然黑连通而不白连通。故只需要递归验证所有白连通块子图即可。

据此,设计 DP。\(f_n\) 表示 \(n\) 个点的黑连通的好图个数。枚举包含 \(n\) 的白连通块点数 \(j\) 即可进行转移。复杂度 \(O(n^2)\)

考虑我们为什么得以进行这个 DP。具体来说,我们先刻画了判定问题的条件。这个条件并不是直接给出的,而是需要通过递归验证。这种情况下,将判定过程直接改为生成过程,DP 过程中进行类似的递归操作,最终得以刻画方案数。

47 CF954H

树上定长路径计数,直接枚举两点计算距离比较困难,原因是不知道 LCA。所以直接枚举两点与 LCA。

具体地,整棵树形态比较特殊。所以只需要枚举两点与 LCA 的深度即可。

直接做是三次方的,但是把代码写出来很容易看出这个形式可以优化到平方。

这个题的重点在于只需要枚举三个点的深度,而后面优化到平方是比较容易的过程。当钦定若干个数不容易计算贡献,原因是有些未知量时,不妨尝试将未知量加入枚举范围内。

48 CF1254E

先观察问题形态。

考虑交换一条边 \((u,v)\) 的点权,不难知道两边子树独立,不可能再次进行交换将某侧的点换回来。所以对于每个数 \(i\),其初始在点 \(i\) 上,不妨假设最终移动到了 \(x_i\),则 \(i\) 移动过去的途径必然沿着树上唯一路径。

考虑对于每个 \(i\),画出有向路径 \(i \rightarrow x_i\),考虑如果存在一条边被同向覆盖两次,则意味着有两个数要通过这条边换到另一侧,但每条边最多使用一次,所以无解。另一方面,每条边正反都必须被恰好覆盖一次,因为每条边都要使用。

如果连边 \(i \rightarrow x_i\),可以得知这个图是一个 \(n\) 个点的环,并且原树上每条边正反均被覆盖恰好一次,所以一个最终点权序列合法等价于 \(i \rightarrow x_i\) 构成了这棵树的一个有向欧拉回路。

据此,设计 DP。\(f_u\) 表示 \(u\) 子树外到了子树内某个点,经过每条边正反一次后,离开了 \(u\) 子树的方案数。将每个儿子子树的已经确定了最多一条出边连向对应的另一棵儿子子树,则得到了一个有向图。这个图如果有环且目前的点不是根则无解,否则有若干条链,方案数则是把这些链首尾相连拼起来的方案数乘以每个子树内部的方案数。此外,给定的信息可能意味着 \(u\) 子树内的起点或终点唯一确定,次时相当于要求某条链是第一条或最后一条,分类讨论计算贡献即可。复杂度 \(O(n)\)\(O(n \log n)\),具体依赖于实现。

这个题的本质是,先刻画交换点权的本质,单独考虑每个点的移动轨迹,从而将点权计数双射成欧拉路径计数。后面的 DP 则是比较经典的,对于每个子树考虑其进入出去恰好一次,内部的形态的一个 DP 流程。而转移过程则需要观察子树之间的关系是怎么样的,从而合并各个子树的信息。

49 QOJ831

这也太困难了。

我们有结论:随便选一个点作为根,考虑一个点集的直径,则必然存在某条直径的某个端点为点集中某个深度最大的点。证明考虑分类讨论一下即可。

将所有点按照深度排序。对于每个点集,钦定其在排列中最靠后的点为代表元进行计数。上面的结论有一个更强的扩展,即对于某个点 \(u\),深度小于等于 \(u\) 且距离 \(u\) 不超过 \(x\) 的点集中任意两个点距离不超过 \(x\)。根据上述结论可以直接证明。

故对于排列每个点 \(u\),我们希望求出在 \(u\) 之前且距离 \(u\) 不超过 \(x\) 的点数,这是很容易使用点分树维护的。记这个值为 \(c_u\),则对于固定的 \(k\),答案即为 \(\sum \dbinom{c_u}{k-1}\)。记 \(cnt_i\)\(c_u = i\)\(u\) 的数量,组合数拆开就是差卷积,NTT 计算即可。

本题的核心是,对点集计数困难,考虑钦定代表元计数。核心观察就是开头提到的结论,观察到这一点,后面的过程相对比较简单。

50 QOJ835

51 QOJ837

这个题,很厉害啊!

\(k=0\) 时,常见解决方法是点分树,不妨考虑点分树能不能运用于图上问题。

显然不能在图上进行分治,考虑拉出一棵图的 DFS 生成树在树上分治。对于每一层,两个点的路径如果经过重心则容易处理,只需要从重心出发进行一次 BFS 处理出到每个目前层内点的距离即可。这一部分复杂度是 \(O(n \log n)\) 的。

还有一种可能是,两点之间路径不经过重心,这是因为 DFS 树上有一些反祖边,通过这些边也可以使两点连通。

根据原题的限制,任意一个点最多在 \(k\) 个简单环上,也就是每个点至多被 \(k\) 条反祖边覆盖。故对于重心来说,横跨子树之间的边至多 \(k\) 条,涉及到的关键点至多 \(2k\) 个。对这些点做与重心相同的事就可以做到 \(O(nk \log n)\) 了。

这个题的核心刻画形式在于思考特殊性质,并且尝试将特殊性质一般化。这种图上给定特殊条件的问题,常常与 DFS 树有关,比如图上最长简单路径长度不超过 \(k\) 可以转化为 DFS 树深度不超过 \(k\),这个题则是经过每个点的环数量不超过 \(k\) 意味着包含其反祖边数量不超过 \(k\),据此将点分治过程在图的某个 DFS 树上考虑,问题得以解决。

52 核桃 S 模拟赛 T4

有根树其实没有意义,问题等价于每次选一条链,将其缩为一个点,对于每个 \(x\) 求进行 \(x\) 次这样操作后树最少还剩几个点。

在树上任意取 \(x\) 条路径,答案必然不超过这些路径并的大小,根据经典结论,可以取等。构造是,找出这 \(x\) 条路径端点的 \(2x\) 个点,求带权重心,每次删掉最大和次大子树内两个点即可。

所以问题等价于,选 \(x\) 条路径最大化并大小。又根据经典结论,必然有一个点选了直径一端,以其为根长剖取前 \(2x-1\) 长的求和即为答案。复杂度 \(O(n)\)\(O(n \log n)\)

53 CF776G

显然 \(a \oplus b\)\(a\) 的关系只和 \(b\) 的最左侧 \(1\) 有关。也就是只和 \(a\) 中十六进制最大的数位有关。枚举最大的数位后数位 DP 即可。

本题核心在于观察减小的充要条件,后面的过程是简单的。

54 P13310

贡献拆开等价于选四个点 \(a,b,c,d\),要求 \(a,b\) 路径点都是黑或无色,\(c,d\) 路径点都是白或无色,且路径没有交点。选的四个点的贡献系数是 \(2^{x}\),其中 \(x\) 为总无色点数减去两条路径上无色点数。

如果没有限制不交是容易的,预处理子树内外信息在 LCA 处统计答案即可。对于限制不交,考虑对路径交部分点边容斥即可,复杂度应该是线性的。

55 CF1750G

显然我们只关心有多少 \(p_{i+1}=p_i+1\)

枚举 LCP,设长度为 \(i\),我们要求 \(p'_{i+1} < p_{i+1}\),并且关心从 \(i\) 开始有多少 \(p'_{j+1}=p'_{j}+1\)

确定数量是困难的,考虑变成在值域上钦定若干个 \(p'_{j+1}=p'_j+1\),然后二项式反演。而钦定的答案相对容易计算。具体地,考虑后面的数在值域上的连续段形态,相当于钦定一些位置和下一个位置合并,推一下式子就可以算出来了。这部分复杂度是平方的。

还有一个问题在于,我们需要对于每个 LCP 做一次二项式反演,这样复杂度是三次方的。但是直接对原序列而非每个 LCP 做二项式反演即可,只需要记 \(f_{i,j}\) 表示 \([i,n]\) 钦定 \(j\) 个的方案数就可以转移了。总复杂度 \(O(n^2)\)

56 CF981H

容易想到应该枚举所有选的路径的交,其显然也是一条路径,设其端点为 \(u,v\)。则我们需要在 \(u,v\) 子树内分别选 \(k\) 个点使得到端点路径边上不交。

设原树以 \(1\) 为根,先考虑 \(u,v\) 没有祖先关系怎么做。

\(f_u\) 表示 \(u\) 子树内选 \(k\) 个点,到 \(u\) 的路径两两边上无交,这些点对应原有序序列的方案数。则对应贡献为 \(f_u \times f_v\)

考虑怎么求单个 \(f_u\),枚举 \(i\) 个点选的不是 \(u\),记其方案数为 \(g_i\),则贡献为 \(g_i \times \dbinom{k}{i} \times i!\)。设 \(u\) 儿子的子树大小分别为 \(s_1,s_2,\cdots,s_m\),则显然有 \(g_i = [x^i]\prod \limits_{j=1}^m (1+s_jx)\)。分治 NTT 计算即可。

对于 \(u\)\(v\) 祖先的情况,\(u\) 点多项式的情况相当于乘以了 \((1+(n-s_u)x)\),并除掉了 \(v\) 对应的 \((1+sx)\),而 \(v\) 的贡献仍然是 \(f_v\)

一个做法是,考虑除的是 \((1+sx)\),而 \(s\) 的本值不同个数显然只有 \(O(\sqrt {deg})\) 个,所以直接暴力除复杂度就是 \(O(n\sqrt n + n\log^ 2 n)\) 的。

还有一个不带根号的做法。具体来说,考虑 \(G_u(x) = \sum \limits_{y} h_y \left(\prod \limits_{z \neq y} (1 + s_zx)\right)(1+(n-s_u)x)\)。我们只需要能求出 \(G_u(x)\) 就能 \(O(deg)\) 计算答案。考虑直接分治 NTT,过程中同时维护 \(\prod (1+sx)\)\(G_u(x)\),每次前者直接对应相乘,后者有一个 \(F_l \times G_r + G_l \times F_r\) 的形式,直接乘即可。复杂度 \(O(n \log^2 n)\)。注意特判 \(k=1\)

此题的核心一步在于枚举路径交集。之后自然地分类讨论 \(u,v\) 的情况。想到用 OGF 刻画后,再考虑一下类似换根的情况即可,最后的分治 NTT 部分需要一些手法。

57 CF750G

这个题有点智慧。

树上两点形态一点都不容易刻画,在这个方向上思考不是很有前途。考虑到 \(x\) 的父亲为 \(\lfloor \dfrac{x}{2} \rfloor\),考虑从二进制角度刻画 \(u,v\) 路径点编号和。

显然 \(u\) 到根路径经过点为所有前缀,所以 \(u,v\) 的 LCA 即为两个数的 LCP。

现在考虑 \(u,v\) 的路径点权和是什么。假设 \(u,v\) 的 LCP 在 \(u\) 中最靠右的位置是 \(x\) 位,在 \(v\) 中是第 \(y\) 位,则对于 \(x\) 之后的每个位置 \(i\),其贡献为 \(\sum \limits_{j=0}^i 2^j = 2^{i+1} - 1\)。则贡献最多为 \(\sum \limits_{i=0}^{x-1} 2^{i+1} - 1 + \sum \limits_{i=0}^{y-1} 2^{i+1}-1\)

而对于 LCP 部分,设 LCP 为 \(a\),则贡献不难算出为 \(a(2^{x+1}+2^{y+1}-3)\)。不难发现 LCP 部分的最小贡献大于后面的最大贡献,所以 \(x,y\) 确定时,\(a\) 唯一确定,为 \(\lfloor \dfrac{s}{2^{x+1}+2^{y+1}-3} \rfloor\)

后面就容易了。相当于是你有若干个 \(2^i-1\),你要取若干使得和为 \(s\)。枚举取了多少个后从前往后背包即可。总复杂度 \(O(\log^5 V)\),但其实随着枚举选的数增加 \(1\),只需要对后缀的 DP 进行修改,可以优化到 \(O(\log^4 V)\)

这个题的第一个关键在于将思考方向从树直接转移至二进制,另一关键点则是发现 \(a\) 唯一确定,而后面的 DP 相对比较经典。这启发我们思路进入瓶颈时,尝试观察是否漏掉了一些性质,某些东西是否是不变量,或者有特殊的范围。

58 杭电多校 1002

我们要做的是,单点修改 \(a,b\),支持回到历史版本,对于某个 \(x\) 查询一段区间依次执行 \(x \gets \max(0,x+a_i-b_i)\) 得到的结果。

这显然是 \((\max,+)\) 矩阵乘法,主席树维护即可。

这个题本质是,显然只需要将询问的 \(k\) 依次分段查询区间值。而线段树维护矩阵是一个经典模型,套用即可。

59 杭电多校 1004

考虑我们枚举 \(|t| = l\),要在一些字符串中选一个相等的长度为 \(l\) 的子串。

考虑变成选后缀,要求任意两个 LCP 大于等于 \(l\)。根据 height 将整个排序好的后缀分为若干段,目标是在每个段内选字符串。这很容易维护。当 \(l\) 增大时,合并相邻段,\(O(n)\) 合并每个字符串对应的下标最大的后缀,复杂度 \(O(n\sum |s|)\)

这个题的本质是,将选子串改为选后缀,而对于后缀,LCP 为 height 区间 \(\min\),所以只需要对每段处理答案。

60 杭电多校 1008

考虑每种数出现次数 \(c_1,c_2,\cdots,c_m\),则方案数为 \(\dbinom{k}{c_1,c_2,\cdots,c_m}\),根据 Lucas 定理,其值模 \(2\)\(1\) 当且仅当 \(c_1,c_2,\cdots,c_m\) 构成了 \(k\) 的一个二进制划分。

然后就乱做了,据此可知只需要考虑 \(b\) 中最多只有一种数出现次数是奇数,并且所有出现次数为偶数的数的出现次数互不相同,然后方案数是一个第二类斯特林数。然后问题变成了查询 \([l,r]\) 中出现次数为奇数的数的最大值和颜色数。由于只需要考虑颜色数不超过 \(\log k\) 的情况,所以直接 xor-hash,主席树二分就可以做到 \(O(n \log n \log k)\)

这个题的本质是,对于 \(\bmod 2\) 的计数题,考虑有意义的方案是什么,这个题则是通过多重组合数的奇偶性将问题简化,而后面的哈希与主席树部分相对简单。

61 CF755G

对于固定的组数 \(k\),枚举选相邻两个的组数 \(i\),不难知道答案为 \(\sum \limits_{i=0}^k \dbinom{n-i}{i} \dbinom{n-2i}{k-i}\),这显然等于 \(\sum \limits_{i=0}^k \dbinom{n-i}{k}\dbinom{k}{i}\)

其组合意义是,从前 \(k\) 个数中选 \(i\) 个数,然后在剩下的数中选 \(k\) 个数。

容斥,枚举选的 \(i\) 个数和后面选的 \(k\) 个数有 \(x\) 个重叠,答案为 \(\sum \limits_{x=0}^k (-1)^x\dbinom{k}{x}\dbinom{n-x}{k-x}2^{k-x}\)

进一步,这等于 \(\sum \limits_{x} (-1)^x\dfrac{k!}{x!(k-x)!}\dfrac{(n-x)!}{(n-k)!(k-x)!}2^{k-x}\),等于 \(2^k \times k! \times \dfrac{1}{(n-k)!} \times \sum \limits_{x} \dfrac{(-1)^x(n-x)!}{x!2^x} \times \dfrac{1}{((k-x)!)^2}\)

考虑到 \(\dfrac{(n-x)!}{(n-k)!} = \dfrac{n^{\underline{k}}}{n^{\underline{x}}}\),所以式子进一步等于 \(2^k \times k! \times n^{\underline{k}} \times \sum \limits_{x} \dfrac{(-1)^x(n-x)!}{x!2^xn^{\underline{x}}} \times \dfrac{1}{((k-x)!)^2}\),NTT 计算即可。

有一个问题是,如果 \(n^{\underline{x}} \equiv 0 \pmod {998244353}\),就会导致分母为 \(0\)。解决方法是,考虑这个式子等于 \(\dfrac{n^{\underline{k}}}{n^{\underline{x}}}\),由于 \(x \leq k\),所以如果这个分母为 \(0\),则 \(n^{\underline{k}}\) 也会包含 \(998244353\),此时若 \(n^{\underline{x}}\) 不含,则值是 \(998244353\) 的倍数,否则考虑将这两个数同时除以 \(998244353\) 进行计算即可。

这题的难点在于,写出 \(O(k^2)\) 的式子后,怎么才能用 NTT 计算。这个式子不能计算的原因是你写成阶乘形式并不能写成两个和与 \(k\) 有关的式子,所以希望找到一个等价的但容易计算的式子。

62 CF1779G

首先可以观察到如果最外层是一个环那么答案是 \(0\),任意两个点可以互相到达。

考虑其他情况。不失一般性地,假设最外层左右两条边都是从上到下,下面的边是从左到右的。考虑找出最靠近右侧的,从下到上的边,则这个包含左下顶点的小三角形内任意两点可以互相到达,我们只需考虑这个三角形和右侧一个梯形之间的结果。

猜测这个结果应该是 \(2c\),其中 \(c\) 是这条线到右侧边的长度,构造是把左边和下边的这一段都取反。实则不然,因为可以看出直接把右边全部取反就可以构造出 \(n\)

继续观察,不难发现最优解只需要保证左边和下边的这一段分别能被到达和到达,所以枚举平行于这条边的那个能转移的位置即可。

复杂度 \(O(n)\)

这个题的突破口在于先考虑一些特殊性质,然后进一步猜测答案并小心验证或给出反例。

63 CF1896F

谁在会做这种题?

首先有解至少要满足 \(s_1=s_{2n}\) 且有偶数个 \(1\)

不妨假设 \(s_1=s_{2n}=1\),否则可以一次操作 flip 这两个位置。

注意到,如果对于任意 \(i \equiv 0 \pmod 2\)\(i < 2n\),有 \(s_i = s_{i+1}\),则一次操作即可复原为全 \(0\),原因是你发现任意两个相邻的 \(1\) 之间都有偶数个 \(0\),且相邻 \(1\) 之间连在一起,对每两个相邻的一组做一下即可。

然后为了使得满足这个条件,依次考虑每个偶数 \(i\),若 \(s_{i}=s_{i+1}\),则填入 \(\texttt{()}\),这两个位置的取反情况必然相同。否则要么填 \(\texttt{((}\) 要么填 \(\texttt{))}\),取决于上一次填的是什么。这是因为要使得括号匹配。

所以至多 \(3\) 次即可。复杂度线性。

这题的难点是,不要试图分析能一次操作得到的所有串的形态,而是考虑一些相对容易构造方案的一次操作的情况。

64 CF1696F

给的信息很多,可能导致想到很多没前途的做法。

考虑以 \(1\) 为根,如果能确定某个点 \(u\)\(1\) 相连,整棵树形态就确定。原因是可以找到 \(1\) 的所有儿子,然后对于每个点确定父亲后就能找儿子。

枚举 \(u\),构造出来后判定一次,复杂度 \(O(n^4)\)

所以说对于这类,信息量很大,解空间大的题,可能需要 BFS 式想题。

65 CF1667D

考虑一条边被删除时,其两端点的度数奇偶性显然相同。

称一条边是奇边,当且仅当其被删除时两端点度数为奇数,偶边同理。

考察原树叶子和父亲的边,显然这条边是奇边。

另一方面,单独考察与一个点相连的所有边,要求若其度数为偶数,则奇边偶边数量相等,否则奇边比偶边多一条。

据此可以按照 DFS 的顺序依次确定每条边的奇偶性。具体地递归计算儿子结果后,即可确定这个点和父亲的边的奇偶性。

若奇偶性不符合对单个点的要求,显然无解。否则考虑对于任意一个点,随意选出一个访问其邻边的方案。我们只需要保证这些边的相对访问顺序固定即可。这样连边显然没有环,所以求一个拓扑序即可。

这题的核心点是寻找不变量,具体地是考察过程中一些固定的性质,也就是边的奇偶性。

66 CF2103E

有解的必要条件是,存在 \(a_i + a_j = k\)\(i \neq j\)。事实上,这也是充分条件。考虑直接给出构造。

具体来说,我们希望任意时刻存在 \(i,j\) 符合上述限制,并且我们希望能任意对 \(i,j\) 进行调整。这是容易的。我们可以在至多两步操作内将 \(i,j\) 换为 \(i',j'\)

不妨假设 \(i=1\)\(j=2\),依次考虑 \([3,n]\) 中的数,从小到大,每次和 \(i,j\) 进行操作就可以使得 \(i \gets j\)\(j \gets x\),然后将 \(i,j\) 调整为 \(i,i+1\)。这样保证了任意时刻都可以将 \(a_x\) 插入到有序前缀的后面那个位置。

最终会构造出来一个 \(a_1,a_2,\cdots,a_{n-2},x,k-x\),其中 \(a_1 \leq a_2 \leq \cdots \leq a_{n-2}\),而后面两个数没有限制。不妨将其调整到某个 \(a_i \leq \lfloor \dfrac{n}{2} \rfloor\),且 \(a_{i+1} \geq \lceil \dfrac{n}{2} \rceil\)\(i\) 后面即可。操作次数是 \(3n\) 级别的。

67 CF843C

显然菊花最优,但是不一定能构造出来。

注意到,由于只能从大连通块向小连通块进行连边,所以每次操作较大连通块都会包含重心,故以重心为根,每个儿子连通块相互独立。两个重心的情况类似。

考虑只有一个重心,我们肯定希望把每个儿子的子树都变为菊花,事实上这是可以做到的。我们先将子树变为链,然后变为菊花。链变为菊花是容易的,考虑怎么变为链。

方法是,我们希望从下往上将所有点加入这条链。先断开重心和儿子的这条边,并添加重心和某个叶子的边,然后每次把这个叶子和父亲的边断开,加入这个叶子到某个其他叶子的边即可。

显然操作次数不超过 \(2n\)

68 杭电多校 1003

对于一条路径,设长度为 \(l\),期望显然是 \(\dfrac{2^l-1}{l} \times \sum p_i\)

不难发现只需要考虑 \(\sum p_i > 0\) 的最大的 \(l\)\(l-O(\log V)\) 这一段长度即可。这是很容易拓扑排序过程中维护的。

还有一个问题是,如何比较 \(\dfrac{2^a-1}{a}s\)\(\dfrac{2^b-1}{b}s'\),即比较 \(bs(2^a-1)\)\(as'(2^b-1)\)。这相当于比较 \(x(2^a-1)\)\(y(2^b-1)\),假设 \(a \geq b\),把 \(2^a\) 拆成 \(2^b2^{a-b}\) 作差即可简单判断。

69 杭电多校 1005

选定 \(x\) 后,考虑依次将每个数移动到对应的位置,操作过程是,不断向后移动 \(x-1\) 格,然后往前移动若干格后一步移动到其位置上。

很遗憾,\([1,x)\) 中的数不能这样移动,原因是可能不够多余的位置往前。

考虑对这些数单独处理,先考虑排列 \(2,1,3,4,5,\cdots\),如何通过操作交换 \(1,2\),写个搜子就能搜出来,然后你就可以任意交换 \(p_1\)\(p_i\),这样每次把 \(p_1\) 交换到要去的位置即可。

70 杭电多校 1007

显然可以 \(a_i \gets \max(a_i,a_{i+1})\) 使得 \(a\) 单调不递增。

容斥。钦定一些 \(b_i < b_{i+1}\),考虑每个被钦定的一个连续段 \([i,j]\),要求每个 \(b_x \geq a_i\),且 \(b_i < b_{i+1} < \cdots < b_j\),方案数显然是组合数,直接 DP 做这个容斥即可。

71 杭电多校 1011

这个过程是考虑每个 \(1\) 后面连续 \(0\) 数量的一段后缀,满足形成了公差为 \(-1\) 的等差数列。对这个公差差分变成询问后缀连续 \(1\) 数量,这个就随便做了。

72 CF734F

注意到 \(a \operatorname{and} b + a\operatorname{or} b = a + b\)

所以 \(b_i + c_i = na_i + \sum a_i\)

\(\sum b_i + \sum c_i = 2n \sum a_i\)

即可唯一确定每个 \(a_i\)。最后判定一下是否符合原来的 \(b,c\) 即可。

本题核心是,\(a \operatorname{and} b + a\operatorname{or} b = a + b\) 的性质。

73 P7172

对询问 \(u,v\),求出 \(u\) 子树内某个叶子 \(x\)\(v\) 子树内某个叶子 \(y\),如果 \(u,v\) 没有祖先关系,答案就是 \(x,y\) 的 LCA。如果能求出 \(x,y\) 的 LCA,判断这个点的深度和 \(u,v\) 深度关系就可以确定 \(u,v\) 是否有祖先关系。

考虑将问题分为两部分解决,分别是求某个点子树内某个叶子,以及如何求两个叶子的 LCA。

对于求某个点子树叶子,考虑按照深度从大到小扫描线,维护目前层的每个点的子树内某个叶子构成的序列,只需要支持单点删除,可持久化平衡树维护即可。

对于查询两个叶子的 LCA,考虑整个过程是从深到浅,每层大部分点都直接跳到父亲,有两个点会合并。这等价于问 \(u,v\) 两个点第一次被合并的时间。Kruskal 重构树即可。

复杂度 \(O(n \log n)\)

74 CF1494F

注意到,切换后的操作只能删去一个菊花图,而切换前的操作能删去一个欧拉路径。

所以很容易通过枚举删的菊花图的中心做到 \(O((n+m)^2)\)

核心在于发现切换后的操作的意义。

75 CF923F

太厉害了,想不出来。

观察可知任意一棵树是菊花时显然无解。

打个表可以注意到对于比较小的 \(n\),只要两个都不是菊花,就一定有解。事实上,我们可以证明对于任意 \(n\) 都有这个结论。

考虑归纳证明,同时给出一个构造。

对于目前的树 \(T_1,T_2\)。分别选出两个叶子,\(a_1,a_2,b_1,b_2\),使得 \(a_1\)\(a_2\) 距离不为 \(2\)\(b_1,b_2\) 距离不为 \(2\),且 \(T_1\) 删去 \(a_1,a_2\) 不为菊花,\(T_2\) 删去 \(b_1,b_2\) 不为菊花。递归构造 \(T_1 \setminus \{a_1,a_2\}\)\(T_2 \setminus \{b_1,b_2\}\)。然后考虑对 \(a_1,a_2\) 的两种映射:\(a_1 \rightarrow b_1, a_2\rightarrow b_2\)\(a_1 \rightarrow b_2,a_2\rightarrow b_1\)。不难发现必有一种符合要求。

考虑什么时候选不出 \(a_1,a_2,b_1,b_2\)。可以发现如果树是菊花图外面挂一个点就会发生这样的情况。\(T_1,T_2\) 中哪个是这类基本对称,不妨考虑 \(T_1\) 是这样。假设中心 \(a\),菊花外挂的点 \(c\),以及 \(a,c\) 中间点 \(b\)\(a\)\(T_2\) 映射到某个叶子,\(c\) 映射到叶子对应的唯一出边,\(b\) 映射到某个不和 \(c\) 映射点相连的点上,其余随意分配即可。

朴素实现复杂度为 \(O(n^2)\),足以通过。

特别地,考虑 \(n\) 比较小,比如 \(n=5\) 时,树如果是一条链,虽然并不是菊花图外挂点,但仍然无法找到符合条件的叶子,所以 \(n\) 较小时需要搜一下。

难点是要敢于猜测,先发现必要条件,然后根据一些手玩或计算机验证从而考虑具体证明。

76 CF1634D

考虑询问 \(1,2,i(i \geq 3)\),假设 \(a_1\neq 0\)\(a_2 \neq 0\),大部分情况是,找出使询问结果最大的 \(i\),则 \(a_i\) 为后缀最大值或 \(0\)。然后假设其为后缀最大值,再对所有 \(x\) 询问 \(1,i,x\),找到最大的,判定 \(x\)\(i\)\(0\)。询问次数 \(2n-4\)

当然这个不对,有一些 corner case,修修补补就对了。

77 QOJ970

考虑二分答案 \(x\),要求选出的环上相邻两数和小于等于 \(x\)

将所有小于等于 \(\lfloor \dfrac{x}{2} \rfloor\) 的数视作 \(0\),其余视作 \(1\),显然要求不能有相邻的 \(1\),且 \(0\) 肯定全部选,此外 \(01\)\(10\) 相邻的要求和小于等于 \(x\)

考虑 \(x\) 从小变大的过程中,会存在 \(1\) 变为 \(0\)。对于单个 \(1\) 来说,其能被选当且仅当左右两个 \(0\) 与其和不超过 \(x\)。当 \(x\) 增大时,会有一段区间使得 \(x\) 能被选。不需要关注左右有 \(1\) 变为 \(0\) 导致其不能选的情况,因为若这样其本来就不是区间最小值,本来就不应该被选。

所以大概就是按照 \(x\) 扫描线,可持久化地维护一下这个东西。

78 CF1129D

\(f_i\) 表示 \([1,i]\) 答案,转移考虑所有符合条件的 \([j,i]\)。类似扫描线的过程,考虑每种数对哪些 \(j\) 有贡献。最终的形式显然是区间加减 \(1\),查询 \(\leq k\) 的数权值和,分块即可。

79 P7446

类似弹飞绵羊,考虑对序列分块,我们希望维护每个数第一次跳出块的位置。求 LCA 时只需要让更大的往上跳即可。

考虑区间 \(a\)\(x\) 的同时,怎么维护每个位置第一次跳出块到哪里。注意到如果其父亲已经到了前面的块,这个点就不用维护了。所以每个位置最多进行 \(O(\sqrt n)\) 次有意义的修改。于是对每个块维护链表表示有意义的位置。每次修改对有意义的位置重构。复杂度显然是 \(O(n \sqrt n)\)

80 NFLS 训练赛 T2

注意到一个长为 \(l\) 的连续段,在整个过程中,只会存在 \(O(\log V)\) 种连续段长度,且容易递归求出。

所以对每种长度排序双指针或者二分即可确定其在哪个段的哪次操作上。对于一段内的查询也是容易进行递归的。复杂度两个 \(\log\)

81 NFLS 训练赛 T3 / LOJ546

容易看出存在一种路径,使得转折点中不存在相邻的两个点不与任何障碍相邻。

对于起点和询问点以及障碍上下左右的点建点,同时还需要记录目前的方向。考虑边的形态是,对于每个点,不妨设其现在在上下方向,要么花 \(0\) 的代价移动到上下的第一个关键点,要么花 \(1\) 的代价走到左侧或右侧的某个关键点,要求这个关键点前不是障碍。扫描线时主席树优化建图即可。复杂度一个 \(\log\)

82 NFLS 训练赛 T4

考虑平方 DP,\(f_{i,j}\) 为第一行前 \(i\) 个和第二行前 \(j\) 个的答案。我们希望按照 \(\max(i,j)\) 递增的顺序处理所有 DP 值。

\(\max(i,j)=k\),考虑计算 \(f_{*,k}\)\(f_{k,*}\),分类讨论 \(k\) 是否被选即可。复杂度 \(O(n^2)\)

具体地,转移形如 \(f_{i,k} = \max(f_{i,k-1},f_{a,k-1}+1)\)\(f_{k,*}\) 类似。特别地,\(f_{k,k}\) 可能通过选同时包含两行的某个矩形而来。

先不管 \(f_{k,k}\),考虑刻画 \(f_{i,k}\) 转移的性质。注意到 \(f_{a,k-1} \leq f_{i,k-1}\),所以只有 \(f_{a,k-1} = f_{i,k-1}\) 时存在有效转移。对于每个 \(i\),我们希望能维护其目前最靠后连续段的起点 \(p_i\)。这个过程相当于将所有 \(p_i \leq a\)\(p_i\) 设为 \(k\) 并将其 \(f\)\(1\)\(p_i > a\)\(f\) 则不变。

对于每个 \(x\) 维护哪些 \(i\) 使得 \(p_i=x\),这个过程相当于集合合并。并查集维护即可。

对于 \(f_{k,k}\),特殊考虑一下即可。

83 AGC017E

考虑 \(a_i\)\(c_i\)。观察到若 \(c_i > 0\),则 \(a_i\) 是多少毫无意义。其左侧拼的要求是 \(b_i = c_i\)。对于 \(b,d\) 同理。

考虑对于每个 \(i\),令 \(x_i = \begin{cases} a_i && c_i = 0 \\ -c_i && c_i \neq 0\end{cases}\),同理令 \(y_i = \begin{cases} -b_i && d_i = 0 \\ d_i && d_i \neq 0 \end{cases}\)。观察到 \(i\) 能在 \(j\) 左侧当且仅当 \(y_i = x_j\)

考虑建图,对于每个 \(i\),连边 \(x_i \rightarrow y_i\)。则每条边对应一个点,一条路径对应一段连续的位置,要求起点编号大于等于 \(0\) 且终点编号小于等于 \(0\)

我们的目标是判定这个图能否被分解为若干不经过重复边的路径,使得起点大于等于 \(0\) 且终点小于等于 \(0\)。必要条件是,对于 \(>0\) 的点 \(u\),有 \(in_u \leq out_u\),对于 \(<0\)\(u\),有 \(in_u \geq out_u\)。但这个并不是必要条件。

进一步,我们声称,对于每个弱连通块,其充要条件为符合上述限制且存在某个点入度不等于出度或某个点编号为 \(0\)

当不存在编号为 \(0\) 的点时,存在某个点入度不等于出度显然是必要条件,否则图只能被分解为欧拉回路,而其起点和终点必须同时为 \(0\) 才行。

我们接下来证明其充分性:

考虑选取任意一个入度小于出度的点 \(u\),根据之前的必要条件,显然有 \(u \geq 0\)。其存在出边 \((u,v)\),若 \(v\) 的入度大于出度,则我们找到了一条 \(u\) 开头 \(v\) 结尾的路径,否则其入度小于等于出度,必然存在之前未被经过的出边 \((v,w)\),然后递归到 \(w\) 做同样的过程,不难发现最终必然能找到 \(u\) 开头的某条符合条件的路径。将其删去后考虑每个弱连通块,若存在入度不等于出度的点则根据归纳符合要求,否则其存在一个欧拉回路,将其拼在 \(u\) 开头的那条路径上对应的点即可。

另一方面,存在点 \(0\) 的弱连通块显然符合要求。

综上,只需要建边 \(x_i \rightarrow y_i\) 后判断上述条件即可。复杂度线性。

84 AGC018C

首先,容易建立费用流模型。\(S \xrightarrow{1,0} i\)\(i \xrightarrow{1,a_i} A\)\(i \xrightarrow{1,b_i} B\)\(i \xrightarrow{1,c_i} C\)\(A,B,C \xrightarrow{+\infty,0}\)。答案即为最大费用最大流。

由于增广路不成环,所以最多经过 \(A,B,C\) 各一次。对于每个右侧点 \(i,j\) 维护 \(i \rightarrow x \rightarrow j\) 的最大费用,对右侧三个点跑最短路即可。复杂度 \(O(n \log n)\)

85 AGC010D

注意到若存在 \(a_i = 1\),结果只和 \(\sum a_i - n\) 的奇偶性有关。

更进一步,考虑同时除以 \(\gcd\) 对总和的影响。发现若 \(\gcd\) 为奇数,总和奇偶性必然不变,否则可能改变。

则我们声称以下结论成立:

\(a\) 中存在 \(1\) 或至少两个奇数,则博弈结果只和 \(\sum a_i - n\) 的奇偶性有关。

考虑根据 \(\sum a_i\) 归纳证明。

边界情况显然成立。

\(a\) 中存在 \(1\),结论显然成立。

否则,我们先证明:若 \(\sum a_i - n \equiv 1 \pmod 2\),则先手必胜。

\(a\) 中至少有三个奇数,选择其中一个操作。操作后 \(\gcd\) 必然不为偶数,同时除以 \(\gcd\) 后得到一个至少有两个奇数的局面,根据归纳假设成立。若 \(a\) 中恰好有两个奇数,显然 \(n \neq 2\),所以 \(a\) 中有至少一个偶数。选择其操作,操作后 \(\gcd\) 必然不为偶数,根据归纳假设成立。故先手必胜。

另一方面,若 \(\sum a_i - n \equiv 0 \pmod 2\),则先手必败。若序列中有至少三个奇数,无论如何操作,得到的序列奇偶性必然改变且至少有两个奇数。若序列中恰有两个奇数,先手操作其中一个后,后手也操作之即可。

这种情况证明完毕。但是考虑到如果 \(a\) 中仅有一个奇数,先手可能存在获胜方案是,选择那个唯一的奇数,使得所有数除以一个偶数从而改变和的奇偶性。所以考虑递归判定序列 \(A\),若 \(A\) 中有至少两个奇数或存在 \(1\) 则直接判定,否则选那个奇数递归判定。

递归层数显然是 \(O(\log V)\) 的,对 \(n\) 个数求 \(\gcd\) 的复杂度是 \(O(n + \log V)\),总复杂度 \(O(n \log V)\)

86 杭电多校 1001

考虑到这个东西大概是矩阵形式,容易得到一个每次算 \(M^{b_i}\)\(O(nk^3 \log V)\) 的复杂度。

考虑优化,注意到你最终只需要求出 \(\sum \limits_{T} M^{\sum \limits_{x\in T}x}\),并且只关心这个矩阵的第 \(n\) 行第 \(n\) 列的值,所以事实上你只关心这个矩阵的第 \(n\) 行的这个向量。而每次为了求出 \(M^{b_i}\),考虑处理 \(M^{0},M^1,\cdots,M^{B-1},M^B,M^{2B},\cdots,M^{B\times B},M^{2 \times B \times B},\cdots\),取 \(B=\sqrt[3]{V}\) 即可。复杂度 \(O(k^3\sqrt[3]{V}+nk^2)\)

87 杭电多校 1006

从高到低数位 DP,你只关心这一位还能往前进位多少,前缀有多少等于 \(l\),有多少等于 \(r\),朴素转移就是 \(O(n^6 \log V)\),足以通过。

88 杭电多校 1010

把平方拆成选两个点,则我们只需要对于每个 \(d\) 计算树上有多少距离为 \(d\) 的点对即可快速计算答案。

这是经典问题,点分治时 NTT 即可,复杂度 \(O(n\log^2n+nk)\)

89 NFLS 训练赛 T3

\(O(n^2)\) DP 是简单的,注意到形式大概是 \(f_i = \max \limits_{j} \{k_jx_i+b_j\}\),要求 \(j\)\(i\) 子树内,所以动态开点李超线段树合并即可。

关于复杂度,我们可以证明其为 \(O(n \log n)\)。具体地,考虑插入 \(n\) 条线段的动态开点李超线段树有 \(O(n)\) 个点。对于合并,复杂度开销在合并某个两棵线段树同时存在的点。我们的做法是直接将第二棵的这个点的线段插入进合并后的树上,若递归过程中成功插入,注意到每次递归会将所有点深度和增加 \(1\),而深度和总共是 \(O(n \log n)\) 量级的,所以递归次数不超过 \(O(n \log n)\),另一方面,若这条线段在插入过程中没有新增节点,则相当于删去了一个节点。总共只会至多删去 \(O(n)\) 个节点,复杂度仍然是 \(O(n \log n)\)

90 NFLS 训练赛 T4 / QOJ3272

考虑如果序列初始就单调不降,那么 chkmin 其实是后缀覆盖,线段树二分就能维护出这个后缀的位置。

考虑原问题,可以发现任意时刻,之前被操作 \(1\) 影响过的位置必然单调不降,其余位置则没有被 chkmin 过。考虑分开维护。单调不降的这个子序列直接套用上述方法,其余位置只需要维护存活的位置 \(a_i \gets a_i + i\),查询区间和,这个是容易处理的。

问题变为怎么求出每个位置 \(i\) 被操作 \(1\) 第一次影响的时间。考虑二分答案 \(mid\),要求判定是否存在时刻 \(t \leq mid\)\(a_i+i\times c_t\geq v_t\)。这等价于判断 \(v_t - i \times c_t\) 的最小值是否小于等于 \(a_i\)。整体二分,过程中维护凸包即可。

91 NOI2025 D1T2 序列变换

先考虑第一问。考虑选择一些点限制其最终权值大于 \(0\),其余点权值为 \(0\),等价于最小化这些点的权值和。

先考虑如何判定这个过程。考虑这些位置为 \(x_1,x_2,\cdots,x_k\),本质上是要将序列划分为 \(k\) 个区间 \([l_i,r_i]\),要求 \(x_i \in [l_i,r_i]\),并且对于每一段,\([l_i,x_i)\)\((x_i,r_i]\) 能分别从前往后与从后往前合并,且 \(a_i\) 足够大。

直接 DP,记 \(f_{i,j}\) 为目前前缀 \([1,i]\)\(x_k=i\),且 \(l_k = j\)\(r_k\) 未知,这些点的权值和最小值。直接转移可以简单做到多项式复杂度。优化是很容易通过在转移中将转移过程进行一些分步来做到 \(O(n^2 \log n)\),瓶颈在于里面有个排序和二分。

对于计数,直接套用上述做法的问题是,我们要对本质不同的最终序列进行计数,但是可能存在若干个状态 \(i,j\) 使得 \(a_i\) 的值最终相同。不难发现此时会存在一个 \([j,x]\) 使得这一段从前往后操作之后全都是 \(0\),显然从后往前操作也会全是 \(0\),只记状态 \(f_{i,x+1}\) 即可。

这样做的总复杂度是 \(O(n^2 \log n)\) 的,vp 的时候写了,QOJ 过了,那就不写平方了,虽然也是容易优化的。

92 NOI2025 D1T3 数字树

有一个 \(O(n^2)\) 的做法是,注意到答案形如 \(2^k\),考虑怎么有道理地求 \(k\),大概是注意到对于两种数 \(i,j\),考虑他们两两 LCA 的那些位置,发现有至多一个形如知道了到点 \(x\) 时 DFS 的方向,就能确定点 \(y\) 的 DFS 方向,并且是双向的,所以并查集合并,答案是 \(2\) 的连通块个数次方。直接实现是 \(56\) 分,B 性质是容易的,只需要对链上两个点判定是否存在新的边,容易做到 \(80\),但是 vp 的时候好像写得常数太大了只过了 \(64\)

在这个思路上想正解有点困难,但是有个结论是,考虑每个点子树内出现恰好一次的颜色构成的集合 \(S_i\),令 \(c\) 为本质不同的大小至少为 \(2\) 的集合个数,答案是 \(2^{2n-1-c}\),我也不会证,等会再想想。

然后有一个很厉害的转化,叫做对于每个点 \(u\) 考虑一个 \(01\) 串,第 \(i\) 个位置表示 \(i\) 是否在 \(u\) 子树内恰好出现一次。则本质上要求所有串的长度为 \(i\) 的前缀,至少有两个 \(1\),本质不同数量。这显然等价于将所有串排序,减去相邻相同的数量。考虑先想办法把所有串按最终结果排序,然后求 LCP 后就能找出贡献的那段区间。注意到每个串的生成方式是,对于每次给定的 \(u,v\),将路径上除了 LCA 的设为 \(1\),其余是 \(0\)。这个是容易通过可持久化线段树合并来维护哈希来求两个串的 LCP,瓶颈是排序,复杂度 \(O(n \log^2 n)\)

93 P9993

考虑分块。类似线段树维护区间历史最值的方法,维护每块的加法标记以及最大历史标记和,简单维护就是 \(O(n\sqrt n \log n)\)。已经足以通过。

对于散块重构可以归并排序,这样可以把 \(\log\) 放在里面。

94 P9067

将每个极大连通块信息全都记在最浅的那个点上,维护这个连通块的下面连着的点的颜色信息,而不记录父亲信息。维护每种颜色的链表,合并时启发式合并,由于颜色范围很大你需要用个 map 维护每种颜色对应的链表,这样复杂度就是 \(O(n \log^2 n)\),当然我承认确实能过且跑的飞快。一个解决方法是用 unordered_map,不过常数不一定小。

换一个维护方式,map 本质是平衡树。对于下面连着的点维护 \((c,i)\) 的有序集合,\(c\) 是颜色,\(i\) 是点编号。这样每次定位连通块合并只需要二分找到所有 \(=c\) 的那些位置。

启发式合并用 finger search 就是 \(O(n \log n)\) 的。

95 P9068

相当于询问 \(\sum \limits_{x>y} [pre_x < lst_y]\)。修改只会影响 \(O(1)\)\(pre,suf\),离线下来 cdq 分治就可以做到 \(O(n\log^2 n)\) 时间,\(O(n)\) 空间。

96 QOJ11272

本质来说就是颜色均摊段的一些扩展应用。

考虑将整个序列分为若干连续有序段。维护数颜色显然等价于问 \(\sum \limits_{c} [pre_c \leq x]\),但是直接对每个 \(c\) 维护 \(pre_c\) 是困难的,因为两种排序的存在,\(pre\) 的变化相对不容易直接维护。

考虑将限制放松,不维护每个 \(pre_c\),而是对于每个 \(c\),找到 \(pre_c\) 所在的连续段,将其贡献记在其区间左端点 \(l\) 上。对于询问,前面整的连续段的答案直接用这个回答,而多出来的一个连续段前缀则想办法用数据结构维护。

对于每个连续段,维护值域线段树,支持分裂合并区间求和,即可支持上述操作。复杂度是 \(O(n \log n)\) 的。

97 NFLS 训练赛 T3

线段树维护分段函数即可。

场上写的是另一个很烂的东西,虽然也过了。

98 NFLS 训练赛 T4 / QOJ4924

树链剖分,每次询问是 \(O(\log n)\) 条重链前缀和 \(O(1)\) 个重链区间,以及 LCA 子树外部分。LCA 到全局最优点可以点分树求出,重链前缀可以离线对每个重链扫然后李超树维护,前缀的最后那个位置还要维护子树内信息,李超树合并即可。对于重链区间,树状数组套李超树。这是我赛时的写法,时间复杂度 \(O(n\log^3 n)\),瓶颈是对树状数组套李超树插入 \(O(n \log n)\) 个结点,常数很小,足以通过。

99 P13129

离线做线段树合并即可。

100 P11621

把等腰直角三角形转为一个贴着某个边的等腰直角三角形,然后做 cdq 分治即可。

101 QO11274

\(x\) 看作 A,将 \(a_i \neq a_{i+1}\) 的间隔看作 B,本质就是询问 ABA 子序列数量。

分块,每块维护 ABA 这个串每个前后缀数量就可以支持合并。为了做到线性空间要离线逐块处理。

102 P7710

\(x\) 根号分治。

\(x \geq B\),枚举所有 \(kx+y\),子树内固定深度的点是同层按照 DFS 序排序的一段区间,要支持 \(O(1)-O(\sqrt n)\) 区间加单点查,分块即可。

\(x < B\),将子树变成 DFS 序区间形式,分块,整块维护每个 \(x,y\) 的贡献和即可。

\(B=\sqrt n\),复杂度 \(O(n\sqrt n)\)

103 QOJ4316

单根号过了,很慢。

分块,对于整块或散块内部的区间,容易在修改时重构块内信息得到。除此之外,重构时维护每个块内最长合法前后缀,如此一来跨块的信息只需要从前往后扫每个块并依次判断是否能包含整一个块。

时间复杂度 \(O(n\sqrt n)\),空间复杂度 \(O(n)\),为了空间做到线性,需要离线对于每个块分别维护结果。我写了,跑了十秒左右。

还有一个 poylog 做法,考虑维护所有连续段,这是容易用 set 维护的,对于询问 \([l,r]\),先把 \(l,r\) 所在的连续段判掉,要问最长的连续段 \([l',r'] \subseteq [l,r]\)\(x\)\(a_l\)\(a_r\) 中。注意到 \(a_l\)\(a_r\) 是一个置换环的一部分,于是对于每个这样的连续段,将其映射到置换环的一个环上区间上,对于每个值环维护树套树,对于环上区间 \([x,y]\),将 \([x,y]\) 在外层线段树上遍历到的每个节点加入一个序列中的区间 \([l,r]\),查询就可以直接做了。时间复杂度 \(O(n \log^2 n)\),空间复杂度 \(O(n \log n)\)

104 QOJ9634

离线做换维扫描线,扫序列维,对于目前扫到的 \(i\),维护每个操作 \(2\) 对应的 \(\max \limits_{j=l}^i a_j\)。把询问差分成前缀形式,则是询问 \([1,t]\) 的区间历史和。对于每次操作 \(2\),将其视为在 \(l\) 时刻开始生效,\(r+1\) 时刻失效。只需要维护给定区间,将区间内生效的点对一个数取 \(\max\),维护区间历史版本和。吉司机线段树维护即可,复杂度 \(O(n+m \log m)\)

105 CF1019E

考虑一般求直径的方法。任取一个点 \(u\),找到距离其最远的点,然后从那个点开始找到距离其最远的一个点。

随便取一个 \(u\),算出所有点到其的一次函数 \(kx+b\),对于每个 \(x\) 容易找到最大的一次函数对应的最远点,问题变为 \(O(n)\) 次询问,每次给定 \(u,x\),求 \(u\) 出发,参数为 \(x\) 时,最远距离。建点分树,对每个点建立李超树即可。

posted @ 2025-06-29 21:37  HappyBobb  阅读(58)  评论(0)    收藏  举报