图论做题记录-2
图论做题记录-2
ARC161E. Not Dyed by Majority (Cubic Graph)
通过较为精湛的打表和猜测分析,我们惊讶地发现,对于任意一组解,能找到与之对应的初始状态的概率并不高,这启发我们随机给出一组解,然后判断其是否可行。那么如何判断一个解是否可行呢?我们考虑一个点要么为 B,要么为 W,这是典型的 2-sat,于是我们考虑用 2-sat 限制这个内容,于是问题在 \(O(n)\) 的复杂度内得解。
AGC056C. 01 Balanced
不难想到将 \(0\) 看作 \(1\),将 \(1\) 看作 \(-1\) 对原序列求前缀和 \(s\),那么我们有 \(|s_i-s_{i-1}|=1\)。考虑对于给出的限制,相当于指出 \(s_{l-1}=s_r\)。我们看出可以利用差分约束限制,即我们将上述式子看作:
因为要求字典序最小,所以每一个位置的 \(s\) 要尽可能大,因此可以跑一遍最短路,上界就是答案对应的 \(s\),然后做一遍差分即可。最短路可以用 01bfs 解决,复杂度是 \(O(n+m)\) 的。
CF1163F. Indecisive Taxi Fee
观察不同的边对答案不同的贡献,我们发现:不在最短路上的边改动后,答案为原最短路和包含这条边的最短路替换边权取最小值;在最短路上的边改动后,答案为原最短路替换边权和不包含这条边的原最短路。注意到原最短路、原最短路替换边权是容易的,接下来考虑如何求解其他的内容。
对于包含某条边的最短路,对于边 \((u,v)\) 容易想到其路径应当为 \(s\to u\to v\to t\) 或 \(s\to v\to u\to t\),不难看出我们只关心 \(s\to u+v\to t\) 和 \(s\to v+u\to t\) 的值,因此可以分别从 \(s,t\) 开始跑一遍最短路,这样可以 \(O(1)\) 求出经过边 \((u,v)\) 的最短路,替换边权是容易的。
对于最短路上不包含某条边的最短路,可以考虑到其他每一条边地最短路总是通过一段最短路上的前缀 + 一段非最短路 + 一段最短路上的后缀得到,那么看出来这条路径不包括最短路上的某些边,可以借由这一点进行操作。更具体的,对于非最短路的一条边,我们求出经过其的最短路上前缀和后缀的信息,即在哪个位置路径开始分离,记为 \(L,R\),那么这两点之间的所有边都有这条路径的贡献,区间取 \(\min\) 即可。这个可以用线段树实现,复杂度是 \(O(\log n)\) 的。
综上,我们可以在 \(O((n+m+q)\log n)\) 的复杂度内解决这道题。
LG3511. [POI 2010] MOS-Bridge
看到最大边权最小,我们想到二分。对于二分出的 \(x\),显然只能选择边权 \(\le x\) 的方向边去走,我们考虑怎样验证新图中是否包含一个欧拉回路。考虑有向图为欧拉图的充要条件:每一个点的出度入度各占其度数的一半,相当于我们需要判断是否存在一种定向方式,使得每一个点的入度恰为 \(\frac{\text{deg}}{2}\)。考虑使用网络流,对每一个边连向其可行定向对应的起点,那么每一个点的度数上界为 \(\frac{\text{deg}}{2}\),存在一种合法方式当且仅当所有边均跑满,也就是最大流。注意对于原图存在欧拉回路而言,还要求每一条边必须至少存在一个可行的方向,这个可以通过控制二分的下界解决。
跑出最优解后,可以根据残量网络进行边的定向,最后跑出一个欧拉回路后输出即可,复杂度是 \(O(\text{AC})\)。
CF1458D. Flip and Reverse
我们考虑在数轴上对应一个字符串:将 \(0\) 看作 \(-1\),相应的 \(1\) 看作 \(1\),从 \(0\) 开始,遇到 \(0\) 向反方向走一个单位长度,遇到 \(1\) 向正方向走一个单位长度,于是我们将每一个字符串在数轴上对应了一条路径。现在考虑操作的影响,通过观察我们发现一次操作相当于选择一个环,将你走这个环的顺序颠倒。也就是说对于原字符串建出的图来说,走边的顺序是不重要的,因为我们可以颠倒走边的顺序,因此我们对于原图的边重新定一个顺序从而找到一个对应字符串字典序尽可能小的方案。
考虑到一个字符串对应的图一定满足其是一个从 \(0\) 出发的欧拉路径,那么我们可以贪心的每一次尝试走 \(0\),如果走 \(0\) 后一定不合法那么只能走 \(1\),否则总有方案使得当前字符串合法。考虑不合法的情况,可以分为以下几种:
- 前驱的度数为 \(0\)。
- 前驱的度数为 \(1\),自己的度数不为 \(1\)。
否则定然存在合法解,于是问题解决,复杂度是 \(O(n)\) 的。
LOJ6271.「长乐集训 2017 Day10」生成树求和 加强版
看到所有生成树的权值和,我们已经迫不及待想要使用矩阵树定理解决这个问题了,然而每一个生成树的权值的定义让我们难以处理。考虑到对于一个树而言,其最终权值的三进制位之间互不干扰,于是我们可以考虑拆位,即考虑第 \(i\) 位为 \(0,1,2\) 的生成树分别有多少个。
对于每一位,我们可以先求出每一条边的权值,进而去求解生成树的权值,然而不进位加法我们处理起来较为困难,如果想要利用矩阵树定理,那么我们需要将其转化成乘法。考虑一个在乘法中具有循环特性的内容:单位根,我们有 \(\omega_{K}^{i}\omega_{K}^j=\omega_{K}^{(i+j)\bmod K}\),这完美符合我们的要求。于是我们可以将权值 \(0,1,2\),分别替换为 \(1,\omega_{3}^i,\omega_{3}^{2i}\)(以下将 \(\omega_{3}\) 简称为 \(\omega\) ),如果边权为 \(0,1,2\) 的生成树分别有 \(A,B,C\) 个,这样可以求出 \(\omega^{0}A+\omega^{i}B+\omega^{2i}C\) 的值,于是代入 \(i=0,1,2\) 即可详细解出 \(A,B,C\) 的值。
考虑在这个过程中,我们较难维护答案的值:我们容易求得 \(w=a+bi\) 的形式,然而关注到 \(\omega^{2}=-\omega-1\),于是所有数字都可以表示成 \(a+b\omega\) 的形式,那么我们可以维护这样一个结构体。对于这样的数,加减操作不必多说,考虑乘法和逆元的影响:
利用高斯消元快速求解这个内容,复杂度是 \(O(n^3\log_3V)\) 的。
LG5470. [NOI2019] 序列
首先问题可以简单用网络流建模:首先建立一个假源点,用于限制恰好选 \(K\) 个位置,也就是源点向假源点连接一条流量为 \(K\),费用为 \(0\) 的边。接着对于每一个位置,认为选择当且仅当其和源点或汇点的连边有流量,即连接源点和 \(A\) 对应的所有位置,汇点和 \(B\) 对应的所有位置,流量为 \(1\),费用为对应的值。然后每一个位置可以两者都选,也就是对应的 \(A,B\) 直接连边,流量为 \(1\),费用为 \(0\)。同时还可以不对应,我们可以新建立两个点 \(p,p'\),用 \(u\to p\to p'\to v\) 表示选择了两个不对应的位置,显然所有边的费用为 \(0\),\(u\to p,p'\to v\) 的流量为 \(1\),因为至少需要有 \(L\) 个位置都选,那么 \(p\to p'\) 的流量最多只能有 \(K-L\)。对这个图跑一遍最大费用最大流即可。
然而考虑到费用流的复杂度较高,难以接受,我们考虑手动模拟费用流的增广过程。可以分为以下几种情况:
- 选择了之前没有选过的 \(a_x,b_x\)。可以直接连接。
- 选择了之前没有选过的 \(a_x,b_y\)。可以直接连接,但是这样会占用一个特殊流量,所以只有在有特殊流量的时候才能连接。
- 选择了之前没有选过的 \(a_x,b_y\),但是 \(b_x,a_y\) 是选过的。可以考虑将连接 \(b_x,a_y\) 的两个点连到一起,这样我们就可以连接 \(a_x\to b_x,a_y\to b_y\),这样可以省掉一个特殊流量。
- 选择了之前没有选过的 \(a_x,b_y\),但是 \(b_x\) 是选过的。可以考虑将连接 \(b_x\) 的点和 \(b_y\) 连到一起,这样我们就可以连接 \(a_x\to b_x\)。
- 选择了之前没有选过的 \(a_x,b_y\),但是 \(a_y\) 是选过的。可以考虑将连接 \(a_y\) 的点和 \(a_x\) 连到一起,这样我们就可以连接 \(a_y\to b_y\)。
显然只有这 \(5\) 种情况最优,并且不难看出我们可以维护 \(a,b\) 都没有选过的位置 \(x\) 中 \(a_x+b_x\) 最大的 \(x\)、当前 \(a\) 没有选过的位置 \(x\) 中 \(a_x\) 最大的 \(x\)、当前 \(b\) 没有选过的位置 \(x\) 中 \(b_x\) 最大的 \(x\)、当前 \(a\) 没有选过但是 \(b\) 选过的位置 \(x\) 中 \(a_x\) 最大的 \(x\)、当前 \(b\) 没有选过但是 \(a\) 选过的位置 \(x\) 中 \(b_x\) 最大的 \(x\) 全部用优先队列维护出来。那么单次增广只需要在这 \(5\) 中情况中找最优即可,复杂度是 \(O(n\log n)\) 的,这个过程实质上是模拟费用流(反悔贪心)。
CF51F. Caterpillar
因为题目中要求毛毛虫除自环外无环,因此对于原图的一个环,我们一定需要将它们缩成一个点,因此考虑对原图进行边双连通分量缩点,对于一个边双连通分量,将其缩为一个点的代价是 \(\text{siz}-1\),其中 \(\text{siz}\) 是当前边双连通分量的大小。
考虑处理缩完点后得到的树,由于毛毛虫满足存在一条链,使得其他点到这条链的距离 \(\le 1\),那么容易看出链上的所有点没有必要被删去,所有的叶子节点也没有必要被删去,也就是说,被合并掉的只有既不是链上的点,也不是叶子节点的点。考虑到叶子节点的个数是固定的,于是我们想要让链的长度最大,找直径即可。关注到直径和叶子节点有重复的部分,简单容斥即可。
对于连通块之间的贡献,可以考虑到只需要将两个连通块直径的端点合并,则新图一定符合要求。汇总上面的所有内容,答案即为
其中 \(\text{cnt}\) 是连通块个数,\(\text{dis}\) 是连通块缩点后的直径长度,\(\text{leaf}\) 是连通块缩点后的叶子节点个数,\(\{1/2\}\) 表示取值为 \(1\) 或 \(2\),更具体的,当连通块缩点后将仅剩一个点时,取值为 \(1\),否则为 \(2\)。可以在 \(O(n+m)\) 的复杂度内计算。
CF475E. Strongly Connected City 2
考虑到一个边双连通分量中定然存在一种定向方式,使得所有点互相可达,因此考虑边双连通分量缩点。对于缩点后的图,不难想到,可以选择一个点,使得其为根时,部分子树指向自己,自己指向剩下的子树,容易证明这种策略可以取到最优。考虑这样连边的贡献:每个点到自己子树内的任意一点都存在一条单向可达路径,两种不同的子树之间也存在一条单向路径。不难看出,当根固定时,前者的答案固定,因此仅需考虑后者,而后者的贡献显然是两种子树大小和的乘积,根据简单的不等式,我们看出两者越接近,乘积越大。因此,假设根节点的大小为 \(\text{siz}\),当一个子树大小和越接近 \(\lceil\frac{n-\text{siz}}{2}\rceil\) 时,答案越大。可以采用背包 dp 解决这个问题,复杂度是 \(O(n^2)\) 的。
CF855G. Harry Vs Voldemort
考虑到对于一个边双连通分量,在里面任意取三个点作为 \((u,v,w)\) 均可行,这启发我们对原图进行边双连通分量缩点,对于一个缩完点后的图,考虑统计它的贡献。不妨枚举每一个点作为 \(w\),那么对于一个大小为 \(\text{siz}\) 的边双连通分量,有 \(\text{siz}\) 种方法。接下来的 \(u,v\) 应该满足不在以 \(w\) 所在边双连通分量为根的同一子树内,这个可以简单容斥。综合分析,我们得到答案即为
其中 \(\text{siz}\) 为每个边双连通分量的大小,\(\text{son}\) 是与该边双连通分量相连的所有点,\(\text{sum}\) 是该边双连通分量为根的条件下,每个点的子树大小。这个式子可以简单树形 dp 做到 \(O(n)\) 统计,不用换根 dp,我们可以仅维护 \(1\) 为根意义下的答案,那么父亲的 \(\text{sum}\) 可以用 \(n-\text{sum}\) 表示。
现在考虑加边对答案产生的影响,不难看出,加边相当于将两个点之间的简单路径上的所有点缩为一个边双连通分量,于是原来这些点对答案的贡献消失,最后新产生的点会有新的贡献产生。这个过程中 \(\text{sum}\) 不变,因此其他点的贡献不变。对于新的点,\(\text{siz}\) 是所有点 \(\text{siz}\) 的简单相加,考虑如何快速维护 \(\sum\text{sum}(\text{sum}-1)\)。只需要对每一个点维护其儿子节点的 \(\text{sum}(\text{sum}-1)\) 的和,那么我们只需要将路径上的点维护的信息相加,减去路径上点的 \(\text{sum}(\text{sum}-1)\) ,就可以得到新点的儿子节点的和,然后新产生节点的贡献也可以按照上面的式子简单计算。合并的过程可以用并查集简单维护,单次操作需要枚举路径上的所有点,然后删除产生新的点,不难看出每个点只会被删除 \(1\) 次,每次只会产生 \(1\) 个点,那么复杂度是 \(O(n)\) 的。
BZOJ3331. [BeiJing2013] 压力
考虑到必须经过的点仅为起点、终点和随意一条路径上的割点,因此建立圆方树,然后简单树上差分即可得到正确答案,复杂度是 \(O(n\log n)\) 的。
CF1763F. Edge Queries
考虑到路径不能经过重复的点,因此我们需要对点双连通分量缩点,建立圆方树。考虑到对于一个点双连通分量,其中的所有边都存在一条路径使得其被经过,那么两个点之间任意一条路径上经过一个点双连通分量内的边都可以统计到答案中,于是一个方点的贡献就是其对应点双连通分量中的边数。特别的,因为没有重边,所以对于只有两个点的点双连通分量,这条边不能算入贡献。答案即为路径上的点的贡献和,用树上差分维护即可。
考虑怎么统计一个点双连通分量中有多少条边。根据题目给出的性质,我们可以简单想出一个点最多被包含在一个大小 \(>2\) 的点双连通分量中,那么只需要对每一个点打上标记,然后枚举每一条边就可以判断其在哪一个点双连通分量内。然而我们有更一般的做法:考虑每条边的两个端点在圆方树上一定存在相邻的方点,这个方点就是所求,于是我们可以先建出圆方树,通过树的结构判断哪一个方点是答案即可,更具体的,答案只可能是两者在树上的父亲方点。总复杂度是 \(O(n\log n)\)。
CF487E. Tourists
关注到不允许走重复点,考虑建立圆方树。并且观察发现一个点双连通分量内的所有点都一定存在一条路径经过,因此一个方点的贡献是其周围所有圆点的权值最小值,可以维护一个 muiltiset
。此时答案就是路径上点贡献的最小值,这个可以用树剖 + 线段树做到单次 \(O(\log^2 n)\)。然而我们发现修改时,需要对周围的所有方点做出修改,即删除原有权值后插入新权值,这样单次复杂度会退化至 \(O(n\log n)\),难以承受。
考虑路径上的圆点贡献在原先定义下是无用的,为了充分利用这个信息,我们可以将方点的权值改为其所有儿子圆点的权值最小值,这样修改时只用修改父亲方点的权值,复杂度下降至单次 \(O(\log n)\)。但此时维护的信息是错误的,因为 lca 处方点的父亲的贡献是没有统计的,但因为其他方点总伴随自己的父亲圆点出现,所以我们特判即可。总复杂度是 \(O(q\log^2 n)\) 的。
LG4630. [APIO2018] 铁人两项
阅读题面发现本题和【CF855G. Harry Vs Voldemort】较为相似,区别仅在于不允许经过相同的点,因此考虑在圆方树上 dp。和之前相同的思路,枚举每一个原点作为中转点,那么其他两个点不能出现在同一个圆点的子树内,用式子来讲就是
这里的定义和上文一样,注意因为图不一定连通,所以这里的 \(n\) 指的是连通块大小。对于后面的和式,我们以类似的思路,考虑维护每一个方点在以 \(1\) 为根的时候的所有儿子圆点的 \(\text{sum}(\text{sum}-1)\) 的和,父亲方点的儿子贡献只需要减掉自己,而父亲方点的父亲的子树的贡献可以通过 \(n-\text{sum}\) 直接得出,那么统计是没有困难的,复杂度为 \(O(n)\)。
LG4244. [SHOI2008] 仙人掌图
看到仙人掌考虑建立圆方树,因为每一个边双连通分量都是一个环,并且在圆方树的邻接表里每一个环都按顺序存储,因此两个点之间的最短路是容易计算的,我们考虑进行树形 dp。
- 对于一个圆点来说,我们可以选择它子树里的两条最长链从而得到一条可行链。
- 对于一个方点来说,我们可以选择两个儿子圆点合并成一条路径,或者选择一个儿子传递给父亲,问题在于如何找到最优的合并点。因为问题要求直径是两个点的最短路,所以如果点双连通分量的大小为 \(\text{siz}\),我们只能每个方向延展 \(\lfloor\frac{\text{siz}}{2}\rfloor\) 个点选择,假设两者的编号分别为 \(i,j\),则路径的长度为 \(f_{i,0}+f_{j,0}+|i-j|\),考虑按照两个方向枚举,这样可以去掉绝对值,然后是经典的单调队列优化,可以做到 \(O(n)\)。
LG6998. [NEERC 2013] Cactus Automorphisms
对仙人掌建立圆方树,考虑怎样的置换是可行的。考虑到能够进行交换的必要条件是两个子树大小一致,而重心以外的点均有一个子树大小 \(>\frac{n}{2}\),那么这个子树一定无法与其他子树交换,于是考虑以重心为根。注意到可能有两个重心,但这两个重心求出的结果相同,且互相不同构,因此可以忽略。
- 对于圆点来说,如果其子树存在有序同构,那么这些子树内的点可以随意乱换,因此贡献是所有等价类大小阶乘的乘积。
- 对于方点来说,如果其为重心,那么它既可以旋转,也可以翻折,因此我们考虑这个环的正串及反串的循环同构与原串相同的方法的个数;而如果不是重心,因为父亲子树是被固定的,所以其只能翻折,因此考虑这个环是否回文,如果回文有 \(2\) 的贡献。
关于树是否同构可以利用树哈希简单判断。然而注意方点判断匹配时要求子树是无序同构的,因此计算圆点的哈希值时各个子树应该是等价的。而圆点计算贡献时要求子树是有序同构的,也就是判断所有环的正序哈希和反序哈希是否存在相同,说明我们要按照顺序给不同的子树不同的哈希函数。
最后需要注意在方点时,如果该方点是仅包含两个圆点的点双连通分量,那么在旋转和翻折时会重复计算,需要特判。精细实现可以做到 \(O(n)\)。
LG5966. [POI 2016] Hydrorozgrywka
仙人掌肯定考虑圆方树,考虑继用普通树上的 dp 设计:令 \(f_i\) 表示从 \(i\) 点出发,不走出 \(i\) 点所在子树是否必胜。显然这个数组只对圆点有意义,因此转移是较为简单可以分类讨论出来的:
-
如果当前点的子树中存在可以到达的必胜点或可以逼迫对方走的必败点,那么这个点必胜。
可以到达的必胜点指的是在当前点子树内所有大小大于 \(2\) 的方点,在其原图对应环上两个方向上的第一个必胜点(没有则不考虑),且到当前点距离为偶数的点。因为我们选择这个方向走,沿途的点都是必败,所以不会提前走到其他的点,而走到这个点时先手可以走入这个必胜的子树,因此先手必胜。
可以逼迫对方走的必败点指的是在所有大小等于 \(2\) 的方点,沿着原图对应边到达的必败点。因为此时后手先走而必败,因此先手必胜。
-
否则如果当前点子树内的没有必胜点的方点的大小和为奇数,那么这个点必胜。
因为先手一定可以通过走奇环来切换先后手的顺序,而因为其他的方点没有使先手必胜的点,从而当后手先走时其必败,因此先手必胜。
我们可以在子树内方点统计有多少个必胜点到当前点的距离为偶数和没有必胜点的环的大小和,那么转移的总复杂度是 \(O(n)\) 的。
然而考虑到我们走完 \(i\) 所在子树后可以接着走子树外的环,那么这个做法是否有正确性?答案是有的。考虑如果存在一个圆点在不走出子树的情况下必胜,说明要么走到了一个非根的结点(这种情况正确性显然),要么说明回到根节点的最后一步是先手走的,进一步说明我们可以在这个点走入子树达到切换先后手顺序的目的,而后面面临的选择都是一样的,那么我们可以根据后面的必胜性决定当前的决策,不难看出我们总能找到必胜策略,因此认为这个点必胜是没有问题的。
这样可以求出以某一个点为起点时的必胜性,对于所有点的必胜性只需要进行换根 dp 即可做到 \(O(n)\)。
LG3180. [HAOI2016] 地图
对于仙人掌建立圆方树,断开中心点到当前点的所有路意味着只能走到子树内部,统计子树内部 \(\le y\) 且出现次数为奇数(或偶数)可以利用莫队 + 分块做到 \(O(n\sqrt{n})\),也可以利用线段树合并做到 \(O(n\log n)\)。
LG9194. [USACO23OPEN] Triples of Cows P
不难考虑在两个圆点之间加入一个方点,因为点 \(n\) 的最后删除的,因此不妨假设 \(n\) 为根,那么删除操作可以看作将所有儿子方点合并到当前点的父亲节点上。对于一个图,两个圆点是朋友当且仅当他们在树上有相邻的方点。
发现你要统计的三元组和【CF855G. Harry Vs Voldemort】【LG4630. [APIO2018] 铁人两项】长的比较像,考虑相似的思路:枚举每一个圆点作为 \(b\),那么 \(a,c\) 一定是 \(b\) 的朋友且互不相同,假设有 \(\text{cnt}\) 个数满足条件,那么贡献为 \(\text{cnt}(\text{cnt}-1)\)。然而考虑到在树的情境下这个内容较难求解,因此可以考虑将 \(\text{cnt}\) 拆成子树内的个数 \(s\) 和子树外的个数 \(t\),那么答案为 \((s+t)(s+t-1)=s^2+2st+t^2-s-t\)。\(s\) 是可以树形 dp 时简单求得的,通过观察可以发现 \(t\) 即为父亲方点的儿子个数,于是也可以简单求得。通过贡献延后计算我们可以得到答案即为
其中第一个求和要求是圆点,第二个符号要求是方点。对于后面的双重和式,是可以通过维护方点 \(\sum s\) 的值快速计算的,因此单次求解的复杂度是 \(O(n)\)。考虑删除一个点带来的影响,不难看出当前点、当前点的儿子和父亲、当前点父亲的父亲和当前点父亲的父亲的父亲会受到影响。
- 对于当前点,因为被删除了,所以贡献会消失,应当减去。
- 对于当前点的儿子,因为被合并了,所以贡献会消失,应当减去。
- 对于当前点的父亲,会删除一个儿子,然后加入很多个儿子,因此 \(t\) 和 \(\sum s\) 都会发生变化,可以减去原先贡献,最后加入新贡献。
- 对于当前点的父亲的父亲,因为儿子的 \(t\) 发生变化了,所以 \(s\) 也会发生变化,可以减去原先贡献,最后加入新贡献。
- 对于当前点的父亲的父亲,因为儿子的 \(s\) 发生变化了,所以 \(\sum s\) 也会发生变化,可以减去原先贡献,最后加入新贡献。
可以利用并查集维护每个点的父亲合到了哪一个点上,这些操作可以在均摊 \(O(1)\) 的时间内完成,因此总复杂度是 \(O(n)\) 的。
LG9167. [省选联考 2023] 城市建造
考虑到如果选择一个点双中的点超过两个,那么如果不选择整个点双,一定不可能使城市之间不连通,因此考虑构建圆方树。称选择一个方点表示选择其对应点双中的所有圆点。如果我们选择了两个方点,不难看出,其在树上的简单路径上的所有方点也一定要选择。通过观察发现,如果以重心为根,那么选择一个方点意味着其父亲方点也要选择,证明考虑非重心方点的父亲子树大小一定 \(>\frac{n}{2}\),如果不选择其他方点,那么这种划分不合理,否则选择的路径一定使得父亲方点被选。这里的重心是在不计方点的前提下统计的。可以考虑对 \(k\) 的取值分开进行 dp,下文对于圆点,\(f_u\) 表示选择 \(u\) 点父亲的合法方案数;对于方点表示选择 \(u\) 点的方案数。
-
\(k=0\)
这种情况下所有连通块的大小一定是一样的,且为 \(n\) 的因数,可以考虑枚举。对于每一个因数 \(d\),考虑当前子树如果大小 \(\ge d\),那么子树内一定有点被选择,根据上面的结论,这个点一定会被选择,否则一定不合法,于是如果此时 \(f_u=0\),说明当前情况不合法。
- 对于圆点,考虑所有大小没有达到 \(d\) 的子树,一定需要和自己合并,否则应当会被选择单独,不会和自己合并。这样可以算出来自己所在的块的最终大小,如果不为 \(d\) 则选择不合法。
- 对于方点,如果儿子中有不能选择的点,那么一定无法成功选择当前方点。
单次复杂度是 \(O(n)\) 的,总复杂度可以做到 \(O(nd(n))\)
-
\(k=1\)
这种情况下所有连通块的大小应该在 \([d,d+1]\) 之间,可以看出 \(d\) 一定为某个 \(\lfloor\frac{n}{i}\rfloor\) 的值,因此可以用整数分块枚举。考虑一个子树大小 \(\ge d\) 的点:
- 对于圆点,考虑所有大小没有达到 \(d\) 的子树,这些子树一定需要和自己合并。而大小 \(=d\) 的子树,可以合并也可以不合并,但合并时要求当前点没有必须合并的子树,否则当前点所在连通块的大小一定不符合条件。大小 \(>d\) 的子树一定需要选择。考虑求出所有必须合并的子树的大小和 \(\text{sum}\),大小 \(=d\) 且可以合并的子树个数 \(\text{cnt}\),和所有大小 \(>d\) 的子树的方案总数 \(\text{prd}=\prod f_v\)。继续分类讨论:
- \(\text{sum}=d\lor \text{sum}=d+1\),说明此时什么都不动就可以,那么方案总数应该加上 \(\text{prd}\)。
- \(\text{sum}=1\),说明此时可以选择任意一个 \(=d\) 且可以合并的子树,加上其他子树选择的方案数,总数应该加上 \(\text{cnt}\times\text{prd}\)。
- 对于方点,不难看出子树圆点都必须选择,那么方案数为 \(\prod f_v\)。
考虑一个大小 \(>d\) 且 \(f_u=0\) 的点,不难看出这个点所在连通块一定不合法,那么当前情况不合法。考虑到这样子我们可能会让所有连通块选择 \(d+1\),那么需要单独减去这部分的贡献。因为最多有 \(O(\sqrt n)\) 种可行的 \(d\),这个部分的复杂度是 \(O(n\sqrt n)\) 的。
- 对于圆点,考虑所有大小没有达到 \(d\) 的子树,这些子树一定需要和自己合并。而大小 \(=d\) 的子树,可以合并也可以不合并,但合并时要求当前点没有必须合并的子树,否则当前点所在连通块的大小一定不符合条件。大小 \(>d\) 的子树一定需要选择。考虑求出所有必须合并的子树的大小和 \(\text{sum}\),大小 \(=d\) 且可以合并的子树个数 \(\text{cnt}\),和所有大小 \(>d\) 的子树的方案总数 \(\text{prd}=\prod f_v\)。继续分类讨论: