计数 + SAM + 计数。
\(\rm \color{black}{E}\color{red}{ternalAlexander}\) 出的神仙模拟赛,我再一次爆零垫底了,不过题目质量很高👍。
A 通用计数
求有多少不同的包含 \(n\) 个点的有标号无根树,满足:对于任何一个点 \(x\) ,都存在点 \(y\) 使得 \(x\) 和 \(y\) 之间有一条边且 \(|x-y| = 1\)。
\(2\le n\le 10^5\)。
容斥 + 多项式求逆。
转化题意将带标号的点 \(1\dots n\) 依次连成一条链,将其划分,并且一个点的两条边不能同时被割去,然后连接成一棵新树。
有个引理:\(n\) 个点 \(k\) 个连通块形成生成树方案数为 \(n^{k-2}\prod_{i=1}^k a_i\)。
枚举合法划分方案(看做一个割掉边的集合)\(P\),记 \(W(P)\) 为划分 \(P\) 产生的方案数,这里提出一个 \(n^{-2}\) 后面再乘回去,所以 \(W(P)=\prod_{i=1}^k a_in\)。
设 \(n\) 个点满足要求的答案为 \(F(n)\times n^{-2}\),现在要计算 \(F(n)\)。
直接计和会发现有的方案重复了,因为没有限定连的是那条边,两个连通块可能重新连上割掉的边合并成一个。
考虑容斥,然后推式子(这里 \(Q\) 是 \(P\) 的父集代表 \(P\) 进一步划分得到的方案): \[ \begin{aligned} F(n)&=\sum_{P}\sum_{P\subset Q}(-1)^{|Q|-|P|}W(Q)\\ &=\sum_{Q}W(Q)\sum_{P\subset Q}(-1)^{|Q|-|P|}\\ \end{aligned}\\ \] 设 \(D(P)=\sum_{P\subset Q}(-1)^{|Q|-|P|}\),表示 \(P\) 的容斥系数。
若 \(P\) 将链划分成连通块 \(\{a_1,a_2\dots a_k\}\),发现各个连通块的 \(D\) 值相互不影响,于是得到 \(D(P)=\prod_{i=1}^kD(\{a_i\})\)。
而连通块的 \(D\) 值是可以 DP 得到的,这里变量为数值代表连通块大小: \[ \begin{aligned} D(1)&=0\\ D(2)&=1\\ D(i)&=D(i-1)-D(i-2) \end{aligned} \] 递推式可以理解为:为了合法最后一条边不能断,对于一条链最后倒数第二条边,断掉对系数可以产生 \(-1\) 的贡献。
对 \(F\) 我们进一步得到: \[ \begin{aligned} F(n)&=\sum_{Q}W(Q)D(Q)\\ &=\sum_{Q}\prod_{i=1}^ka_inD(a_i)\\ \end{aligned} \] 再巧妙地设 \(G(i)=i\cdot n\cdot D(i)\),我们只要枚举第一个连通块的大小: \[ \begin{aligned} F(n)&=\sum_{Q}\prod_{i=1}^kG(i)\\ &=\sum_{i=1}^nG(i)F(n-i) \end{aligned} \] 哇塞是个卷积,\(G\) 可以由 \(D\) 得到,那么就可以分治 FFT 得到 \(F(n)\) 了。
或者(这里)用多项式求逆解决,计算 \((1-G(x))^{-1}\) 即可。
复杂度 \(\mathcal O(n\log n)\)。
1 | const int N = 4e5 + 9; |
B 屏蔽词汇
给出串 \(S\),每次询问 \(S\) 的一个子串 \(T\),求出至少要往 \(S\) 中插入多少个分隔符使得 \(T\) 不再是 \(S\) 的子串。
\(3\le n,q\le 10^5\)。
SAM + 线段树合并。
贪心的想,每次找到 \(T\) 在 \(S\) 中最早出现的位置,然后在最后一个字符之前加一个分隔符,继续做下去。(考场上没想到线段树合并就删了 SAM 像这样写了 \(\mathcal O(n^2)\) 暴力。)
那么先把 \(S\) 串扔到 SAM 里面,考虑维护子串出现位置集合,那就每个节点挂一棵线段树。
建出 parent 树后,每个节点就需要维护子树中所有线段树的并,就用到线段树合并。
这样对于询问,在 parent 树上倍增找到代表子串 \(T\) 的节点,然后贪心做。
同时需要将计算过的答案记忆化。
复杂度是 \(\mathcal O((n+q)\sqrt{n}\log n)\) 的,证明:
设询问子串 \(T\) 长度为 \(L\),分类讨论:
- \(L\le \sqrt{n}\):我们贪心一次的复杂度 \(\mathcal O(c\log n)\),\(c\) 为 \(T\) 的出现次数,\(c\) 上界是 \(\mathcal O(n)\) 的;但是加上记忆化之后,发现长度 \(\le \sqrt{n}\) 的串一共 \(n\sqrt{n}\) 个,总复杂度 \(\mathcal O(n\sqrt{n}\log n)\)。
- \(L>\sqrt{n}\):贪心时每次向后跳 \(L-1\) 个单位,所以产生贡献的位置集合大小不超过 \(\sqrt{n}\),总复杂度 \(\mathcal O(q\sqrt{n}\log n)\)。
1 | const int N = 4e5 + 9; |
C 数位规划
对于一个长度为 \(n\) 的由 \(0 \sim 9\) 组成的数字串 \(S\),定义 \(S\) 的优秀度为:在 \([L,R]\) 范围内的,且在 \(S\) 中作为子串出现过的整数的个数。
给出 \(L,R,n\),求所有长度为 \(n\) 的 \(S\) 的优秀度的之和。
\(n\le 400\),\(L,R\le 10^{18}\)。
太难了,先咕着。