组合计数选做

CF2122E

注意到实际上的贪心路径只有一条,就是走到不能再往右走了然后拐下去,显然如果在前面就拐下去是不优的。然后推一下式子可以发现要求构造一个序列 \(a\) 满足所有 \(a>0\) 的位置开始的最小前缀和 \(\ge 0\),从后往前 dp ,优化一下值域的范围,复杂度 \(O(nk^2)\)。

CF2124F2

做法很多。首先划分等价类去重,这个很容易可以观察到条件是一个形如 \(1,2,\cdots,x\) 的段下一段的起点不能是 \(x+1\)。然后考虑 dp,设 \(f_{i,j,k}\) 表示当前填到第 \(i\) 个点,当前段开头数字为 \(j\),当前数字为 \(k\),直接转移复杂度是 \(O(n^3)\) 的。

优化的方式是,注意到转移中除了一次数组的平移以外,其余的要修改的点只有 \(O(n)\) 个,而平移操作显然可以直接记录偏移量完成,复杂度 \(O(n^2+nm)\)。

CF2127F

我们要计数的是和的和,所以考虑拆贡献。把贡献拆成如下形式:第 \(p\) 位是最大值 \(a\),第 \(p+1\) 位是 \(b\),那么贡献会累加 \(a-b\)。枚举 \(a,b\) 后经典容斥统计剩下的数的方案数,可以得到:

\[(n-2)\sum_{a\ge 1}\sum_{0\le b<a} (a-b)\sum_{i=0}^{n-3}(-1)^i \binom{m-2a-b-i(a+1)+n-4}{n-4} \]

看起来很大坨但是注意到 \(ia\le m\),用曲棍球把 \(b\) 合并后直接枚举复杂度就是 \(O(m\log m)\) 的了。注意特判 \(p=0\) 的情况。期望做法其实是利用序列的对称性直接去掉 \(b\) 的枚举,不过代数推导保平安了。

CF2134F

画出真值表,然后发现我们可以将 \((0,2)\) 和 \((1,3)\) 分为两组,组间的数贡献都为 \(1\),组中的不同的数贡献为 \(2\),其余为 \(0\)。这样的话我们想到对两组分开求解,最后归并即可。对于组内,我们实际上只需要求出 \(f_{i,j}\) 表示将组内的数分成 \(i\) 段,造成的贡献为 \(j\) 的方案数即可。枚举段数和开头颜色,然后再枚举断点个数,利用组合数计算的复杂度是 \(O(n^3)\) 的,最后将两组合并是一个卷积,也是 \(O(n^3)\) 的。

QOJ20297

记三个部分为 \(A,B,C\),直接枚举前 \(n\) 个中三个部分分别含有的个数 \(a,b,c\)。注意到 \(|a-c|\le b+1\) 且 \(a+b+c=n\),那么枚举完 \(b\) 后枚举 \(a\) 的范围是 \(O(k)\) 的,复杂度 \(O(k^2)\)。

然后考虑求解,我们的限制只有不能出现 \(AA\) 和 \(CC\),考虑以 \(B\) 分成 \(b+1\) 段,每一段内部只能是 \(A,C\) 交错。写出 GF,有 \(F(x,y)=1+x+y+2xy+x^2y+xy^2+\cdots=(1+x)(1+y)(1-xy)^{-1}\),要求的是 \([x^a][y^c]F^{b+1}(x,y)\)。提取系数可得答案为:

\[\sum_s \binom{b+1}{a-s}\binom{b+1}{c-s}\binom{b+s}{s} \]

最后乘上选择出 \(a,b,c\) 个数的排列数就是第二问答案。第一问直接排列数算就行。复杂度 \(O(n+k^3)\)。

CF2228E2

经典利用组合意义拆开平方,得到:

\[\sum _{x\le y} c_xc_y(n-y+1) \]

先考虑静态求解,分类讨论:

  • \(c_x,c_y\ne -1\),直接前缀和统计即可。
  • \(c_x=-1,c_y\ne -1\),我们实际上要求的就是对于所有合法的方程的解,\(c_x\) 这一位上数的和,在乘上 \(c_y(n-y+1)\) 即可。这个东西和上面 CF2127F 一样,根据对称性就是求 所有合法的 方程的解的第一个数之和,利用组合意义直接化简组合数式子可以得到答案为 \(\binom{m+k-1}{k}\),这是一个定值,所以只需要维护满足要求的 \(c_y(n-y+1)\) 之和即可。
  • \(c_x\ne -1,c_y=-1\),和上面的类似,只不过这回变成求 \(c_x(n-y+1)\) 之和。
  • \(c_x=-1,c_y=-1\),统计出满足要求的对数之后,根据对称性显然是求 所有合法的 方程的解的前两个数 的乘积之和。求这个的方法也有很多,用生成函数或者化简组合数式子可以得到答案为 \(\binom{m+k-1}{k+1}\)。

静态询问就解决了。发现上面的过程可以轻松上线段树维护,只是维护的量较多,可能比较大。

CF2030G2

计数问题先考虑判定,也就是给定区间后找最优的 \(x\)。感受一下可以发现 \(x\) 取到所有数字的中位数最优,原因很简单,可以发现一个区间的伸长长度就是 \(\frac{1}2(|l_i-x|+|r_i-x|-r_i-l_i)\),去掉定值相当于让 \(\sum |l_i-x|+|r_i-x|\) 最小,所以答案就是取中位数。

现在还是不太好做,先对区间离散化使得端点互不相同,同时我们求出的中位数一定是一段区间,令区间左端点为中位数。接下来拆贡献,枚举中位数和一个左半边区间并计算方案数。此时需要分类讨论,根据中位数是某个区间的 \(l_i\) 还是 \(r_i\),可以得出左右半边选择的区间数的差值,暴力枚举并利用组合数计算,复杂度 \(O(n^3)\)。

注意到所有左半边区间对应的方案数都是一样的,因此可以合并计算,复杂度优化至 \(O(n^2)\)。然后注意到这个组合数显然可以范德蒙德卷积优化,于是就做完了,复杂度 \(O(n)\)。

AGC070C

根据 QOJ20297 的经验,我们还是将序列按照平局分段,每一段内只能是 \(A,B\) 交错。但是此时我们段之间是有限制的,因此不能简单拆开计算。我们考虑计算如下内容:令 \(F(a, b, k)\) 表示由 \(a\) 个 \(A\) 和 \(b\) 个 \(B\) 组成的序列,有 \(k\) 个空隙满足两边不同,且满足前缀条件的序列个数。

翻译一下,其实就是从 \((0,0)\) 走到 \((a,b)\),共 \(k\) 个拐点且不触碰 \(y=x+1\) 的方案数。算这个肯定考虑反射容斥,设 \(f(a,b,k)\) 表示不要求前缀条件的方案数,分奇偶讨论后直接插板法即可得到方案数。问题在于反射容斥后的 \(k\) 如何处理。

注意反射容斥的核心在于构造路径的双射,那么我们分讨一下:

  • 如果碰到 \(y=x+1\) 后,反射后的路径第一步是向上的。为了构造双射,我们把触碰到 \(y=x+1\) 后的第一步去掉,这样最后走到的是 \((b-1,a)\),且拐点数相较于反射前会减 \(1\),方案数即为 \(f(b-1,a,k-1)\)。
  • 如果碰到 \(y=x+1\) 后,反射后的路径第一步是向右的。和上面类似,为了构造双射,我们把触碰到 \(y=x+1\) 后的第一个向上走及其以前所有的向右走全部去掉,拐点数显然还是减 \(1\)。枚举触碰后向右走的次数 \(i\),方案数即为 \(f(b-1-i,a,k-1)\)。

综上可以得到一个关键结论:

\[F(a,b,k)=f(a,b,k)-\sum_{i\ge 0} f(b-1-i,a,k-1) \]

对后面的求和使用范德蒙德卷积优化,求一个 \(F(a,b,k)\) 是 \(O(1)\) 的,总复杂度 \(O(n)\)。

P17551

首先考虑给定 \(T\) 如何求解 \(f(T)\),发现直接贪心比较不对,考虑二分答案。二分答案 \(k\) 后我们一定会用前 \(k\) 个 A 去匹配,除了这些 A 以外的 A 可以看做 C,现在问题就转化为能否匹配出 \(k\) 组 ABC,这个就可以直接贪心了。

既然 \(f(T)\) 可以二分答案求解,考虑将最终贡献转化为 \(\sum\limits_{k\ge 0}\sum [f(T)\ge k]\)。枚举 \(k\) 后进行 dp,设 \(f(i,x,y)\) 表示考虑 \(1\sim i\),还有 \(x\) 个 A 和 \(y\) 个 AB 等待配对的方案数,答案就是 \(f(n,0,0)\),复杂度 \(O(n^4)\)。

实际上这个 \(k\) 的唯一作用是判断当前填的 A 是不是前面的 A,而我们要对所有 \(k\) 进行计数,也就是我们可以随意钦定前面的 A 到哪结束。设 \(f(i,x,y,0/1)\) 来表示当前的 A 是前面的还是后面的,答案就是 \(f(n,0,0,1)\),复杂度 \(O(n^3)\)。

posted @ 2026-11-02 11:50  UKE_Automation  阅读(4)  评论(0)    收藏  举报