loading

计数题没做

ABC225H Social Distance 2

所有已知位置会将序列划分为 \(k+1\) 个部分,对于每个部分,考虑求出在其中填 \(j\) 个数的贡献 \(f(j)\)(只考虑这部分之内的贡献),然后答案即为 \(\sum_{p_1+p_2+\cdots+p_{k+1}=m-k}\prod_{i=1}^{k+1}f_i(p_i)\),这个东西可以卷积优化到 \(O(n\log^2n)\)。

考虑怎么求 \(f_i(j)\),不妨假设第 \(i\) 段左右都有填好的数,那么若填的数分别为 \(a_{i-1}=b_0<b_1<b_2<\cdots<b_j<b_{j+1}=a_{i}\),则内部贡献为 \(\prod_{p=1}^{j}(b_{p+1}-b_p)\)。考虑它的组合意义,就是在所有段内各选一个点的方案数,而要算上划分的方案数可以用插板法解决,就是我们假设长度 \(len=a_{i}-a_{i-1}\),我们借 \(j\) 个元素过来并在其中选 \(j+1\) 个元素和 \(j\) 个插板共 \(2j+1\) 个数,然后将 \(j\) 个插板扔掉形成空隙,空隙的位置代表填的数的位置(显然共 \(len-1\) 个空隙),由此可得当两边都有填好的数时,方案数为 \(f_i(j)=\dbinom{a_i-a_{i-1}+j}{2j+1}\)。

对于其他特殊情况,若只有一边有填好的数,那么另一边的贡献不能算,方案数为 \(\dbinom{a_1-1+j}{2j}\) 或 \(\dbinom{n-a_k+j}{2j}\)(注意总元素数少了一个);若两边都没有填好的数,此时 \(k=0\),方案数为 \(\dbinom{n-1+j}{2j-1}\)(少了两个)。

那么怎么卷积优化到 \(O(n\log^2 n)\) 呢?可以分治 NTT 做,另一个更清新的做法是每次选择次数最小的两个多项式乘起来,这个过程就是合并果子(也可以叫哈夫曼树),用堆维护即可,这段可以证明是 \(O(n\log^2n)\) 的,但是我不会。

CF1264D2 Beautiful Bracket Sequence

不难发现存在一个最优解使得选的字符串是括号嵌套,即 (((((...))))),考虑枚举中间(即最后一个 ( 和第一个 ) 之间的位置),但发现不一定最优。进一步观察到存在一个分界点使得左边左括号数和右边右括号数相等,显然分界点取这里一定最优,因为往左走和往右走都一定不优。枚举法分界点和括号数量即可,复杂度 \(O(n^2)\),过掉 easy ver。

考虑优化,设左侧左括号、右侧右括号数分别为 \(p1,p2\),两个 ? 数分别为 \(s_1,s_2\),把式子写出来:\(\sum_i (p_1+i)\dbinom{s_1}{i}\dbinom{s_2}{p_1-p_2+i}\),拆掉括号 \(p_1\sum_i \dbinom{s_1}{i}\dbinom{s_2}{p_1-p_2+i}+\sum_i i\dbinom{s_1}{i}\dbinom{s_2}{p_1-p_2+i}\),不妨考虑右边(左边严格弱于右边),吸收恒等式 \(\sum_i i\dbinom{s_1}{i}\dbinom{s_2}{p_1-p_2+i}=\sum_i s_1\dbinom{s_1-1}{i-1}\dbinom{s_2}{p_1-p_2+i}=s_1\sum_i i\dbinom{s_1-1}{s_1-i}\dbinom{s_2}{p_1-p_2+i}=s_1\dbinom{s_1+s_2-1}{s_1+p_1-p_2}\)。复杂度 \(O(n)\)。

ARC083F Collecting Balls

考虑到球数和操作数相等,显然要求每次操作都恰好消掉一个球。对于这种题,套路性的考虑对行列分别建点,一个 \((x,y)\) 的求就连一条 \((x,y+n)\) 的边,这样每条边就相当于一个球。考虑给每条边定向,边指向谁就代表这个球被哪个操作消掉。这样每个点只能有一个入边,所以定向后原图是一个外向基环树森林,没定向前显然就是基环树森林了(如果不是答案为 \(0\))。

显然树边只有一种定向方式,而环有正反两种定向方式(考虑到无重点且二分图,所以奇环大小必然 \(\ge 4\)),枚举环的定向方式,假设对于一个点 \(x\),他代表横坐标为 \(x\) 的操作,考虑它的入边的另一端 \(fa\) 和它的儿子 \(u\),显然若 \(u<fa\) 则 \((u,x)\) 这条边要比 \((u,fa)\) 更先操作,考虑将这个关系建图连边,将边视为新图上的点,\(u\rightarrow v\) 代表 \(u\) 要比 \(v\) 后操作,由于 \(u\rightarrow v\) 至少要满足 \(x_u+y_u>x_v+y_v\),所以此图一定是 DAG。而由于一条边只可能会有至多一个父亲,所以新图是一张森林。森林的拓扑序个数很好求,答案就是 \(\dfrac{|S|!}{\prod_{i\in S}siz_i}\),\(S\) 代表点集,\(siz_i\) 代表子树大小。由于最终要将原图所有连通块的答案归并起来,所以 \(|S|!\) 的贡献就被约掉了,而最终乘一个 \(n!\) 即可。复杂度线性。

P7154 [USACO20DEC] Sleeping Cows P

将牛视作左部点,牛棚视作右部点,如果一个匹配是极大的,那么假设最大的没匹配的右部点的为 \(p\),那么要求所有 \(s_i\le t_p\) 的左部点强制被选。枚举第一个没选的 \(s_q\),那么所有 \(t_i\ge s_q\) 的所有 \(i\) 都要被选,随便列个 dp 求一下匹配的方案数即可,比如设 \(f_{i,j}\) 表示考虑完 \([i,n]\) 的所有 \(s\),已经匹配了 \(j\) 个位置的方案数,由于 \(i\) 越小限制越小,所以后面的没匹配的必定可以匹配前面的。复杂度 \(O(n^3)\)。

考虑优化。发现我们并不在乎这个 \(q\) 是谁,我们只关心一段前缀是否全被选择。考虑不枚举 \(q\) 而是在状态里加一维 0/1 表示是否存在没被选的数。然而上面的 dp 状态很不好转移,考虑一个新的状态,先将 \(s_i,t_i\) 升序排序,若 \(s_i=t_j\) 则 \(s_i\) 更靠前。从前往后做 dp,设 \(f_{i,j,0/1}\) 表示前 \(i\) 个点,有 \(j\) 个左部点没匹配,是否存在没选的左部点。那么对于限制,我们只需要在第三维为 1 时强制右部点参与匹配即可。这种状态设计不失为一种匹配类问题的好方法。时间复杂度 \(O(n^2)\)。

P7888 「MCOI-06」Distinct Subsequences

首先需要知道本质不同子序列有一个经典 dp,由于太经典我不想写,反正要维护一个 \(s=\sum f_i,f_i\) 的总和,\(f_i\) 表示以字符 \(i\) 结尾的数量。考虑计数转期望,可以看错对于一个位置等概率的更新 \(f_{a_i}\) 和摆烂,由于等概率所以求期望就相当于求平均数,将两种情况的结果加起来除掉二即可,最后别忘了乘 \(2^n\)。复杂度 \(O(n+\lvert\Sigma\rvert)\)。

当然这个做法也可以用直接计数解释:维护只考虑前 \(i\) 个元素不同子序列的 \(s,f\) 之和,转移考虑选或不选,将两种情况加一下,由于 \(s,f\) 都是总和所以求新总和他俩不用变,但 1 要变成 \(2^{i-1}\) 以表示前面的元素任选。最后,所有 \(f_j(j\neq a_i)\) 也要乘二,表示这一位任选。直接做是 \(O(n\lvert\Sigma\rvert)\),发现瓶颈在于最后的乘二,在开始处乘 \(2^{-i}\) 在要求值时乘 \(2^i\) 即可,做到和上面一个复杂度,但不太优美。

P3349 [ZJOI2016] 小星星

经典题。

首先能很容易的写出一个 dp 式子:设 \(f_{i,j,S}\) 表示树上 \(i\) 节点对应的标号为 \(j\),子树内的标号集合为 \(S\),转移需要枚举补集的子集,复杂度 \(O(3^n\operatorname{poly}(n))\)。

发现瓶颈在于枚举子集,考虑优化,思考一下,枚举子集的作用是为了防止不重复标号,我们不想要这个限制,于是考虑容斥,钦定这棵树的节点集合是 \(S\) 的子集,这样复杂度就是 \(O(n^3)\) 的了。考虑到答案是编号互不相同,转化成节点集合恰好是 \(\{1,2,\cdots,n\}\),这样就能顺利子集容斥了,容斥系数是 \((-1)^{n-|S|}\)。复杂度 \(O(2^nn^3)\)。

子集容斥:打个比方,设 \(f_S\) 是恰好为 \(S\) 的答案,\(g_S\) 是至少为 \(S\) 的答案,则我们可以得到 \(g_S=\sum_{S\subseteq T}f_T\),反演一下变成 \(f_S=\sum_{S\subseteq T}g_T\)。这道题 \(g\) 是至多,所以 \(\subseteq\) 的方向要变一下。

posted @ 2025-12-07 15:04  dcytrl  阅读(15)  评论(0)    收藏  举报