Loading

计数杂题

更新的时候决定倒序

CF1809G Prediction

等价于说是任意一个前缀,除了最后一个数之外的最大值和最后一个数之差大于 \(k\)。有可能赢的部分是一个前缀最大值,从后往前 dp 这些部分。容易写出一个 \(O(n^2)\) 的做法,根据 1608F 的套路容易优化成 \(O(n)\)

EGOI2022 legowall

行之间是无所谓的,只考虑列设 \(f_n\) 代表 \(n\) 列的答案,\(g_n\) 代表所有情况,\(f_{n}=g_n-\sum_{j=1}^{i-1}f_jg_{i-j}\)。看到模数不让我们卷积!

然后我发现我不会多米诺排放。

思考行数为 \(2\) 的情况。直接状压凸不凸出来即可。注意到行之间顺序是无关的,所以只用记凸出来的个数即可,直接暴力转移,复杂度 \(O(nm^2)\)

设定一个阈值 \(B\),当 \(n\le B\) 时跑第一种,否则跑第二种。容易发现 \(B=(nm)^{\frac{2}{3}}\) 时最优。

CF1815D XOR Counting

给定 \(n,m\),求所有 \(\sum_{i=1}^{m}a_i=n\) 的非负整数序列,可能的 \(\bigoplus_{i=1}^{m}a_i\) 的值的和模 \(998244353\)

\(0\le n\le 10^{18},1\le m\le 10^5\)

\(m>2\),考虑取 \(x,\frac{n-x}{2},\frac{n-x}{2},\dots\),就可以取便所有和 \(n\) 同奇偶的数。而 \(m\) 个数和为 \(n\),异或起来的值一定和 \(n\) 同奇偶,所以自然就取便了所有值。

于是只有 \(m=2\) 的情况了。即 \(a+b=n,a\operatorname{xor} b\) 的不同可能的和。

考虑数位 dp,\(f_{i,0/1}\) 代表前 \(i\) 位的答案,\(g_{i,0/1}\) 代表前 \(i\) 位的方案数,最后的 \(0/1\) 代表是否进位。

\(n\) 这一位是什么分类讨论即可。不妨设这一位是 \(1\),有如下转移:

\(f_{i,0}\gets f_{i-1,1}+f_{i-1,0}+g_{i-1,0}\times 2^{i}\)
\(f_{i,1}\gets f_{i-1,1}\)

\(g\) 的转移是非常类似的。

code

CF1770E Koxia and Tree

显然在决定一条边时两侧点的数量是确定的,这个东西看起来对每条边是独立的,转换为求期望,根据期望线性性求每条边的贡献和即可。记 \(f_u\) 代表 \(u\) 上有标记的概率,两侧点的个数为 \(c_u,c_v\)。那么一条有向边 \(u\to v\) 的贡献即为:

\[\frac{1}{2}(f_uf_vc_uc_v+f_u(1-f_v)(c_u-1)(c_v+1)+(1-f_u)f_vc_uc_v+(1-f_u)(1-f_v)c_uc_v)\\ \]

对于 \(f_u,f_v\) 的维护,分类讨论一下。\(f_u=\frac{1}{2}f_uf_v+\frac{1}{2}((1-f_u)f_v+f_u)=\frac{1}{2}(f_u+f_v)\)\(f_v\) 同理。

code

CF1821F Timber

\([1, n]\) 的区间里放 \(m\) 棵树,每棵树的高度为 \(k\)。求有多少种放置树的方法,满足:

  1. 每个树都在整点上,且每个点最多只能放一棵树。
  2. 存在一种砍倒树的方案,使得树倒了之后不会越界,也不会有某个点被超过一棵树占据。你可以自由选择树向左倒(也就是占据区间 \([x - k, x]\))或者向右倒(也就是占据区间 \([x, x + k]\))。

求方案数。\(1\leq n, m, k\leq 3\times 10 ^ 5\)

先考虑有一个序列怎么倒,显然是从左往右贪心,能往左倒就往左倒。计 \(f_{i,j}\) 代表最后倒在了 \(i\),共有 \(j\) 棵树的方案数。转移显然是

\[2f_{i,j}\to f_{l,j+1}(i+k+1\le l\le i+2k)\\ f_{i,j}\to f_{l,j+1}(i+2k+1\le l)\\ \]

显然可以写成关于第一维的生成函数,\(F_j(x)=(2\sum\limits_{t\ge k+1}x^t-\sum\limits_{t\ge 2k+1}x^t)F_{i-1}(x)\)。那么答案可以写成 \(\sum\limits_{i=0}^{n}[x^i](2\sum\limits_{t\ge k+1}x^t-\sum\limits_{t\ge 2k+1}x^t)^m=\sum\limits_{i=0}^{n}[x^{i-m(k+1)}](2\sum\limits_{t\ge 0} x^t-\sum\limits_{t\ge k}x^t)^m=\sum\limits_{i=0}^{n}[x^{i-m(k+1)}](\frac{2-x^k}{1-x})^m\)

\((\frac{2-x^k}{1-x})^{m}\) 上下同时二项式定理展开。得到 \([x^{i-m(k+1)}](\frac{2-x^k}{1-x})^{m}=\sum_{p}\sum_{q}[kp+q=i-m(k+1)]\binom{m}{p}(-1)^{p}2^{m-p}\binom{m+q-1}{q}\)。枚举 \(p\),后面 \(q\) 的部分是一个前缀和,那么就做完了,复杂度 \(O(n)\)

code

如果不会生成函数,还可以组 合 意 义。类似的 dp,记 \(f_{i,j}\) 代表考虑到了第 \(i\) 位,递推如下:

\[f_{i,j}\gets f_{i-1,j}\\ f_{i,j}\gets 2f_{i-k-1,j-1}-f_{i-2k-1,j-1}\\ \]

可以看成格路计数问题。假设一开始在 \((0,0)\),你可以向 \((1,0)\) 方向走一步,贡献是 \(1\),或者向 \((k+1,1)\) 方向走一步,贡献是 \(2\),再或者是向 \((2k+1,1)\) 方向走一步贡献是 \(-1\)。最后求走到 \((n,m)\) 的值。

枚举最后一种有多少个,即可算出答案:

\[\sum_{i=0}^{m}(-1)^i\binom{m}{i}2^{m-i}\binom{n-(2k+1)i-(m-i)(k+1)+m}{m} \]

code

如果想不到组合意义怎么办?直接容斥!

设第 \(i\) 棵树最后倒下的位置是 \(p_i\)。这个 dp 告诉我们 \(p_i-p_{i-1}\ge k+1\),然后对于 \(p_i-p_{i-1}\le 2k\) 的部分有一个 \(2\) 的贡献。

先给 \(n\) 减去一个 \(m(k+1)\),于是现在限制变成了 \(p_i-p_{i-1}\le k-1\) 的有 \(2\) 的贡献。考虑容斥,钦定 \(i\) 个区间 \(\ge k\),方案数是 \(\binom{m}{i}\binom{n-m(k+1)-ik+m}{m}\)。二项式反演一下,答案为

\[\begin{aligned} ans&=\sum_{i=0}^{m}2^{m-i}\sum_{j=i}^{m}(-1)^{j-i}\binom{j}{i}\binom{m}{j}\binom{n-m(k+1)-jk+m}{m}\\ &=2^m\sum_{j=0}^{m}(-1)^{j}\binom{m}{j}\binom{n-m(k+1)-jk+m}{m}\sum_{i=0}^{j}\binom{j}{i}-12^{-i}\\ &=2^m\sum_{j=0}^{m}(-1)^{j}\binom{m}{j}\binom{n-m(k+1)-jk+m}{m}2^{-j}\\ \end{aligned} \]

殊途同归了。

CF838D Airplane Arrangements

一架飞机有 \(n\) 个座位排成一列,有 \(m\) 名乘客依次上飞机。乘客会选择一个目标座位,然后选择从前门或者后门上飞机走到目标座位,如果目标座位已经有人坐了,他们会继续往前走,在走到第一个空位后坐下,没有就不坐。

求有多少种方案使得每个人都坐下了。

我们发现不好描述两边走,也不好描述走不了。考虑增加一个位置 \(n+1\),连成一个环,这样两边走可以刻画成顺时针/逆时针,而没地方坐就是走到了 \(n+1\)。。那么问题转化为顺时针或者逆时针走,随机一个目标位置降落,走到目标位置之后的第一个空位,\(n+1\) 号点没有被占据的概率。显然最后 \(n+1\) 个位置会被占据 \(m\) 个,如果 \(n+1\) 这个位置也可以降落,那其实这 \(n+1\) 个位置每个位置被占据的概率是一样的。所以 \(n+1\),没被占据的概率是 \(\frac{n+1-m}{n+1}\),方案数即为 \(\frac{n+1-m}{n+1}(2(n+1))^{m}\)

CF1528F AmShZ Farm

给定 \(n,k(1\le n\le 10^9,1\le k\le 10^5)\) 求长度为 \(n\) 的序列 \(\{a\}\) 的贡献和,对于 \(i\in [1,n],\sum [a_j\ge i]\le n\)。其贡献定义为每种颜色的出现次数的 \(k\) 次幂之和。

和上题一样,建立一个 \(n+1\) 号点,形成一个环。最妙的一步来了,我们尝试把环旋转 \(1,2,\dots n\) 步,显然每一步旋转后贡献是一样的,且一定不合法,所以计算所有序列的贡献最后再除以 \(n+1\) 就是答案。那显然每个数又是一样的,所以计算一个数的贡献再乘以 \(n+1\) 即可。那么就转变为了计算某种数的贡献,可以得到下面算式。

\[\sum_{i=0}^{n}\binom{n}{i}n^{n-i}i^k \]

使用斯特林数普通幂转下降幂,得到答案。

\[\sum_{j=0}^{n}{k\brace j}\binom{n}{j}j!(n+1)^{n-j} \]

HDU7077 Pty Loves Sequence

问有多少个长度为 \(n\) 的序列满足 LIS,为 \(1\sim \max\) 的序列。另外还需要询问 \(1\sim n\) 的数在这些序列中出现的总次数。

枚举最大值,枚举在什么位置然后假设这个子序列是第一次出现去重即可。

容易发现每个数出现概率相同,那么直接除以最大值就是次数。

注意模数不是质数。

ARC133F

给定正整数 \(N\),以及数列 \(A_0,A_1,A_2,...,A_N\)。你有 \(\frac{A_i}{10^9}\) 的概率使得初始的 \(x=i\)。然后你要做下面的操作 \(K\) 次。

  • \(\frac{x}{N}\) 的概率减 \(1\)
  • \(1-\frac{x}{N}\) 的概率加 \(1\)

求最后变成 \(y\) 的概率 \(\bmod 998244353\)

\(1\le N\le 10^5,0\le A_i,\sum A_i=10^9,1\le K\le 10^9\),输入的所有数都是整数。

把一个数 \(x\) 想象成一恰有 \(x\)\(1\) 的长度为 \(n\)\(01\) 串。于是操作相当于等概率选择一个位置反转。想出这一步估计就够神仙了。既然如此我们只需考虑再经过了 \(K\) 轮后有几个 \(1\) 即可。注意我们并不关心一开始每个 \(1\) 在什么位置。

实际上我们想要知道从 \(a\)\(1\) 变成 \(b\)\(1\) 的方案数。这里需要考虑每个位置有多少轮是翻了那里,原先就是 \(1\) 的位置翻偶数次是 \(1\),原先是 \(0\) 的位置翻奇数次是 \(1\),所以我们要求即为 \(k![x^Ky^b](y\cdot \frac{e^x+e^{-x}}{2}+\frac{e^x-e^{-x}}{2})^a(y\cdot \frac{e^x-e^{-x}}{2}+\frac{e^x+e^{-x}}{2})^{N-a}\)。设 \(P=(y+1)e^{x},Q=(y-1)e^{-x}\)。那么原来的生成函数可以写成 \(\frac{1}{2^N}(P+Q)^a(P-Q)^{N-a}\),不管尝试,考虑求后面的部分。考虑所有的 \(a\),列出最终的生成函数 \(\sum\limits_{a=0}^{N}A_a(P+Q)^a(P-Q)^{N-a}\)。把后面两项二项式定理展开,化一化可以转换成 \(\sum\limits_{i=0}^{N}w_iP^iQ^{N-i}\)。而 \(w_i\) 通过计算发现等于 \([z^i]\sum\limits_{i=0}^{N}A_i(z+1)^i(z-1)^{N-i}\)。而答案的生成函数也可以表示成 \(K!\sum\limits_{i=0}^{N}w_i(2i-N)^{K}(y+1)^{i}(y-1)^{N-i}\)。于是我们要解决的问题变成了:

给定一个序列 \(C\),求 \(\sum\limits_{i=0}^{N}C_i(z+1)^i(z-1)^{N-i}\)

这个问题显然可以分治NTT在 \(O(n\log^2n)\) 的时间解决,但其实可以通过换元(或者复合)在 \(O(n\log n)\) 的时间解决。

考虑求出 \(G(z)=\sum\limits_{i=0}^{N}C_iz^i(z-2)^{N-i}\)。这东西你把后面二项式定理展开一下就可以卷了。然后代入 \(z+1\) 就可以得到原式,即 \(\sum\limits_{i=0}^{N}g_i(z+1)^{i}\)。这玩意也可以二项式展开然后卷。

JOISC2020 Day2 遗迹

对于一个长度为 \(2n\)\(1,2,...,n\) 中的每个数都恰好出现两次的一个数列进行 \(n\) 次操作,每次选择每个值中位置最靠后的保留,其余减 \(1\),减到 \(0\) 即出局。
现在给定最后那些位置保留下来,求有多少个初始局面符合条件。
\(1\le n\le 600\).

神仙转换。考虑从后往前枚举每个位置是否保留以及最后的值,显然如果从后往前考虑某个位置在某次被保留了,那么对于前面的位置不可能顶替它。维护一个集合代表还有哪些数可以选择,每次选择不大于其初始高度的最大的值作为最后的值。如果不存在,那么它就是要寄了。

然后考虑计数。从后往前dp,把集合记进状态里。对于不保留的位置,它的高度可以在集合的一段前缀 \(0\) 里选择。这时我们先不考虑每个高度又两个,把这两个当做不同的选择。设前缀 \(0\)\(j\) 个,在其之前已经有 \(CntBreak\) 个位置不保留,那么就有 \(2j-(j+CntBreak)=j-CntBreak\) 种选法。然后考虑保留的情况。枚举最后的高度 \(x>j\),计算 \(x\) 后面连着几个 \(0\),假如是 \(k\),那么就有 \(k+2\) 种选择。

接下来考虑优化,尝试只记录 \(j\) 一个状态。对于不保留的情况已经足够了。否则考虑 \(x>j+1\),此时不会影响 \(j\) 的变换,先不填这个位置,也就是方案拖后计算。否则枚举 \(k\) 代表可以把第二维扩展成 \(k\)。然后有 \(\binom{CntProtect-j}{k-1}\) 选法,\(i\)\(k+1\) 种填法。剩下 \(k-1\) 个数填 \(k-1\) 种数,互不相同,是一个独立的问题也可以dp求。设 \(f[i,j]\) 代表 \(i\) 种数填 \(j\) 个位置。有转移 \(f[i,j]=f[i-1,j]+f[i-1,j-1]\times j+f[i-1,j-2]\times j\times (j-1)\),然后相当于要用 \(f[k-1,k-1]\)

两个dp,总复杂度 \(O(n^3)\)

ABC214G

链接

二维完全错排问题,给定排列 \(p,q\),问有多少个 \(r\) 满足 \(r_i\ne p_i\)\(r_i\ne q_i\)

\(1\le n\le 3000\).

类似一维的错排,考虑容斥,即钦定 \(k\) 个位置 \(r_i=p_i\)\(r_i=q_i\)。那么我们考虑把值相同的下标连一条边(神仙思路),然后对于每个连通块分别计算答案再组合起来。对于只有一个点的连通只有一种选法。否则对于一个连通块记 \(f[i,j]\) 代表大小为 \(i\) 的环选 \(j\) 个位置。考虑给每条边中间加一个点,即转换为找一个大小为 \(j\) 的匹配。断环成链,设选了一个位置相当于选了其后面的位置,那么等价于在 \(2i-1\) 个位置中选 \(j\) 个不相邻的。方案数为 \(\binom{2i-1-j+1}{j}\)。强制选断掉的那条边,方案数为 \(\binom{2i-j-1}{j-1}\)

把每个连通块组合起来其实就是个背包,具体可以看代码。

Code

ABC238Ex Removing People

\(n\) 个人排成一个圆,给定每个人的朝向。一共 \(n-1\) 次操作,每次选择一个人,然后将其看到的第一个人删掉并有代价即为两者距离。
这里距离的定义为以朝向为正方向,之间隔了几个人。并不是最短距离。求代价的期望值。
\(1\le n\le 300.\)

感觉最难的还是转换问题。考虑一个删除排列 \(P\)\(P_n\) 是最后剩下的那个。那么可以从后往前,也就是 \(P_n,P_{n-1}...\) 这样逐个确定每个值是在哪。而这时相当于确定之后有两个情况,在 \(P_{i+1},P_{i+2},...,P_{n}\) 里这些已有的选最靠近自己的那两个,看是否满足条件。

暴力的思维是 \(O(n!)\) 枚举,通常这样的暴力都可以用dp优化,因为有很多冗余的状态。显然对于已经确定的两个位置,之间的那些位置和这两个位置之外的部分就无关了。那么考虑区间dp。不过这是个环先得断环成链。之后记 \(f[i,j]\) 代表往开区间 \((i,j)\) 填的方案数。\(i,j\) 是已经填好了。转移考虑枚举一个 \(k\) 作为区间内第一个被选的位置。\(c_1\) 代表 \(k\) 有几种选择(选择 \(i\) 还是 \(j\))。有方程 \(f[i,j]=\sum\limits_{k=i+1}^{j-1}\binom{j-i-2}{k-i-1}f[i,k]f[k,j]c_1\)。这里组合数代表目前状态共有的 \(j-i-1\) 种选择去掉 \(k\) 再选 \(k-i-1\) 放到前面去。

然后记 \(g[i,j]\) 代表代价,最后答案即为 \(\dfrac{\sum\limits_{i=1}^{n}g[i,n+i]}{n!}\)。转移类似,不过这里需要计算 \(k\) 的贡献(不计算 \(i,j\) 互相的贡献)。需要记录一个 \(c_2\)。具体细节可以参考代码 45-48 这几行。感觉比写在这里清楚。

code

CF1470E

给定一个长度为 \(n\) 的排列 \(p\),每次可以将一个区间 \([l,r]\) 反转,代价是 \(r-l\)。不能反转相交的区间,求代价不超过 \(m\) 的情况下字典序第 \(x\) 小的排列的第 \(y\) 个数。有 \(q\) 组询问。

\(1\le n,q\le 5\times 5,0\le m\le 4.\)

类似子序列自动机啥的,记一个 \(f[i,j]\) 代表长度为 \(i\) 的排列至多有能量 \(j\) 啥的有多少方案。这个可以 dp。然后考虑求答案的时候就有一个 \(O(n)\) 的做法。考虑使得每次能量减一,这样就可以 \(O(poly(c))\) 做了。那么二分一段使得这一段不变,那么搞一个比不变小的部分的前缀和即可。分类讨论后发现还有一种情况,就是不完全不变,然后下一个位置比不变还大,这个也可以二分出位置,于是就做完了,复杂度 \(O(nc^{2}+qc\log c)\)

NWRRC2018 Forgotten Land

给定 \(n\) 个点的树,树上每个点有一个颜色 \(c_u\)。求把树划分成若干个集合,每个集合的贡献是一个关于集合内点以及集合任意两点路径上的点的颜色的并的颜色数量的函数。一个划分的贡献是所有集合的贡献,求所有划分的贡献。

\(1\le n\le 5000, 1\le m\le 10.\)

发现答案只和语言的个数相关,那么可以考虑一个语言的集合,对于集合外的颜色的点删除,这样形成了若干个连通块。一定是在某个连通块内取若干个点,记对于一个语言集合 \(S\) 这样的方案数是 \(f_S\)。容易发现这样会算重。可是如何去重?记 \(g_S\) 是真正的答案。\(g_S=f_S-\sum_{T \subset S, T\neq S}g_T\),移项之后反演即可,那么可以直接 fmt。

posted @ 2022-02-05 18:34  Semsue  阅读(228)  评论(0编辑  收藏  举报
Title