组合计数 ☆ 概率期望 Solution Set
主要是真的数数水平低于人均啊。
而且效率有点小低,不如写点简略题解。
其实是集训拉的题单。
AGC005D
一眼容斥,将冲突看成边的形式,位置连边构成若干链。选择一条边就是一个冲突。
然后每个链可以单独考虑生成函数然后卷起来,或者每个链直接做 DP。
motivation: 容斥,然后就很自然。
AGC026D
有一个关键观察是一行确定之后上下两行的颜色可以大致确定(要么唯一,要么因为下面红蓝相间所以可以填两种红蓝相间的)。
然后可以 DP。记 \(dp_{i,0/1}\) 表示(多叉)笛卡尔树上第 \(i\) 个结点的方案数/最后一行红蓝相间的方案数。这样往下面的转移比较好表示。
motivation: 贡献形式不同的只有两种。
UOJ310 ※
先写出每个巧克力的形式幂级数,指数采用异或的方式,系数带 \(2\),大概长成 \((1+2x^{a_i})\)。答案就是 \(x^0\) 的系数。
利用 xor-FWT 的定义式 \(b_i = \sum_j (-1)^{|i \cap j|} a_j\) 大概看得出来每一项单独 FWT 后系数只有 \(-1\) 和 \(3\),然后和的 FWT 就是 FWT 的和……那就全加起来 FWT 解出每一项 \(-1\) 和 \(3\) 的个数 \(p,q\),然后该项就是 \((-1)^p 3^q\),最后 IFWT 回去就好了。
motivation: FWT 定义式及系数观察。
CF708E ※
首先多少次操作炸掉多少个格子比较好算。
然后有个显然的 \(O(n^5)\) 暴力,记 \(dp_{i,l,r}\) 表示第 \(i\) 行保留下了 \([l,r]\) 的格子。
正难则反,我们算所有的减去没有交集的,写出一个更麻烦的式子,但是实际上现在只跟前后缀有关,道理上来说应该是更容易一些的。
注意到左右两边并没有本质区别,同时发现减去的两个东西一个只跟 \(l\) 有关,一个只跟 \(r\) 有关。先考虑优化状态定义,我们去掉 \(l\) 这一维,转而枚举 \(r\) 后发现 \(l\) 跟 \(l\) 有关的是一段前缀,同时因为左右两边没有本质区别可以通通优化掉,这样是 \(O(n^2)\) 的。
motivation: 结构观察,正难则反。
ARC096C
简单数数题。先容斥多少个不满足要求(出现 \(0\) 次或 \(1\) 次),钦定多少个没出现,先带上组合数系数。然后与这几个数无关的可以随便选。现在有两个问题,一个是没被钦定的数可以和被钦定的数的集合放一块儿,第二个是被钦定出现不超过一次的咋算。
那就再枚举被钦定的 \(i\) 个数放进了 \(j\) 个非空集合,同时加一个 \(0\),\(0\) 所在的集合表示这个集合应该是空的。问题就变成了 \(i+1\) 个数入 \(j+1\) 个非空盒。那就是 \(S_{i+1,j+1}\)(懒得写啥 matrix 巴拉巴拉的,这个是二类斯特林数),可以从两个方向确定其组合意义,这里已经采用了一种了。
然后没被钦定的数放进被钦定的数构成的 \(j\) 个非空集合非常好处理,因为反正挑一个并起来也不会冲突,就是个快速幂的事情。
motivation: 容斥,然后就很自然。
AGC008E
因为这个题给的是 \(a\) 不是 \(p\) 很阴间。结合样例可以大致看出来建出所有的 \(i \to a_i\) 形成的要么是个单环要么是个内向基环树,并且环上挂的都是链。
显然环环间可以结合,这是另外的事情;内向基环树只能自嗨。那就乘法原理先上,然后分类讨论。
首先是内向基环树,一个链还原回去要么只有一种方法,要么有两种方法,要么没有方法,跟两条链之间的距离和长度有关系,可以自己手画。
然后是环,奇环可以有两种,偶环可以一次拆开。那就对所有大小相同的环 DP 就好了。比较麻烦。
motivation: 画图,分类讨论。
UOJ667 ※
首先建树这个做法很多题都有(比如 JOJO,虽然那个是 DFS 转树),做题的时候想不到真是太蠢了!
然后树上 \(O(k^4)\) 的 DP 非常的愚蠢,就直接大力搞。
然后有个很巧妙的处理方法是我们把答案表示成关于一个元的多项式,那么 DP 转移的时候就可以把次数拆开转移。
但是只有这个转移的话效果并不明显,因为我们还需要注意限制。那么向下转移的时候,我们储存上面用了多少个 \(R\) 和 \(B\),这样效果就体现了,时间复杂度 \(O(k^2)\)。
motivation: 栈转树,系数拆开,限制的处理。
AGC009E ※
擦掉 \(k\) 个数再写上一个数,容易想到 \(k\) 叉树。
那么答案可以用深度的形式表示出来……当然这样非常蠢笨,因为这样会算重,\(k\) 个 \(1\) 聚起来还是 \(1\),这并不是很好处理的。
返回到题目本身的小性质。那么记我们最终造出的数 \(k\) 进制小数为 \(C\),容易写出很多跟 \(C\) 本身有关的限制。然后再考虑 \(\sum C_i\),也就是 \(C\) 的每一位的和,其模 \(k-1\) 为 \(n\),考虑进位就好了。还有个容易忽略的限制是 \(\sum C_i \leq n\)。
有一个毋庸置疑的结论是如果叶子全是 \(1\) 根也为 \(1\)。那么我们把所有的 \(0\) 变成 \(1\) 造出一堆类似的限制即可。
最后我们 DP \(C\) 的每一位,记 \(dp_{i,j,0/1}\) 表示搞了 \(i\) 位,\(\sum C_i = j\),最后一位是否不为 \(0\)。把满足限制的加进答案就好了。
motivation: \(k\) 叉树,可以用限制限定答案的范围而不是一股脑全加。
AGC013E
这个平方不好处理,并且不好用一种元表示。直接考虑组合意义,等价于在一个区间内放两个球(可以重叠)的方案数。
那么记 \(dp_{i,0/1/2}\) 表示第 \(i\) 个位置到最近的隔板放了几个球,分特殊格子和普通格子转移。矩阵快速幂优化即可。
motivation: 组合意义。
AGC016E
首先考虑一个集合 \(S\),如果想保留集合 \(S\),那么对于所有 \((x,y)\) 使得 \(x \in S\) 应该删掉 \(y\)。类似的如果我们想保留一对点 \((u,v)\),那么要满足所有的 \((u,x)\) 和 \((v,x)\),我们选择弄掉 \(x\)。
注意到,是 \((u,x)\) 和 \((v,x)\),两者一定程度上互不影响,我们可以拆开考虑。
那么就思考一个点怎么不被干掉。那么存在的一个毙掉关系 \((u,x)\),我们要在之前保留 \(x\),之前存在一个毙掉关系 \((x,y)\),我们要毙掉 \(y\)……这样每个关系就可以推出与我无关或者钦定一个必须被毙掉,被毙的向活下来的那个连边。保留 \(u\) 就是类似于一个以 \(u\) 为根的内向树的结构(容易发现如果一个点有两个爹那 \(u\) 肯定就去世了)。
如果 \((u,v)\) 能够同时活下来,那就把 \(u,v\) 为根的内向树拼起来,如果有一个点存在两个爹那就不能同时活下来。建边的话只需要考虑倒推处理就好了。
motivation: 为什么不问问强大的太阳神呢?
AGC019F
自己有个奇妙的想法。大概是说答案是 \(\max(n,m)\) 再减去期望经过 \(y=x\) 的次数。
后面那个很好理解,前面那个……我们假装多的那一种我们能全猜对就行了。反正就是莫名其妙啊,我觉得非常正确!
motivation: ???
AGC018E
有点搞笑哈你这个题。
首先中间那个矩阵可以在任意位置睡觉,那就是在矩阵里面走的点的个数(也可以用长度描述)。
然后第一个和第三个矩阵可以容斥选出四个关键点,然后第二个矩阵枚举起始和终止点,用长度描述转成坐标,可以直接做。
motivation: 为什么要去问飘飘蛋呢?容斥,点数转坐标。
AGC023E
容易发现要对每一对位置计数。有一种考虑方法是算这一对位置产生逆序对的概率,最后乘上总方案。
先考虑总方案,发现按 \(a_i\) 排序之后(还需要钦定一个偏序关系,但这不重要,你可以直接假设每个 \(a_i\) 不同)每个位置能选的个数是确定的。然后再考虑算一对逆序对 \((i,j)\) 出现的概率。
不妨设 \(j<i,a_i>a_j\),求此时选出的 \(p_i<p_j\) 的概率。首先因为更高的 \(a_i\) 占掉了一个更小的值,那么对于所有的 \(a_k\) 满足 \(a_j < a_k < a_i\) 的选择方案数都少了 \(1\),同时假设 \(a_i\) 被赋值为 \(a_j\),那么总共 \(a_j(a_j-1)\) 对 \((p_i,p_j)\) 有一半都会存在逆序对。
同理考虑 \(i<j,a_i>a_j\),这时候不好搞,就求顺序对,最后带一个总方案。总方案那部分可以二维偏序,其他的可以线段树处理。
motivation: 每一对考虑,方案数为概率乘总方案数。
AGC012F ※
先声明我并不会证明。
先将 \(a\) 排序,然后 \(b\) 需要满足:
- \(a_i \leq b_i \leq 2n-i\);
- \(\nexists (i,j), b_j<b_i<b_{i+1}\);
- \(\nexists (i,j), b_j>b_i>b_{i+1}\)。
这三个东西比较直观,但是怎么证是充分的有点困难……当然我们没必要考虑这些啊!
那就采用 DP 的方法。第一个限制限制转移范围,第二个限制可以描述成上一个选择了 \(p\),这次选了 \(q\),那么 \((p,q)\)(可能出现 \(p \geq q\),不太影响,翻过来就好了)里面的所有数都不能选。
用加数的方法不太直观,我们从某个确定的状态更好,也就是最后中位数确定,考虑倒推。记 \(dp_{i,j,k}\) 表示确定了 \(b\) 的后面 \(i\) 位,在满足第一个限制的情况下,选出的第 \(i\) 个数是可以选择的 \(j\) 个数里面第 \(k\) 大的。注意加入的数要去重。这里还是贴个代码吧!
if(!dp[i][j][k]) continue;
int p=j,q=k;
if(a[n-i]^a[n-i+1]) ++p,++q;
if(a[n+i]^a[n+i-1]) ++p;
for(int l=1;l<=p;++l) add(dp[i+1][p-max(Abs(q-l)-1,0)][min(l,q+1)],dp[i][j][k]);
我不是很懂证明,但是转移的过程及状态的设定也够有意思了!
motivation: ???直觉与丢失的证明,从确定的状态开始转移,分析限制特征。
AGC020F ※
首先确定一个东西就是在 \([0,1]\) 内选俩实数相等的概率为 \(0\)。
然后一眼状压,鉴定为怪异复杂度。
那么我们考虑固定最长的线段(为了避免转移出现环)并记其小数点后为 \(0\),然后再枚举小数点后的大小关系并离散化(根据上面的结论没有线段的小数点后是一样的),环上就只有 \(nc\) 个坐标。这样就能直接状压暴力转移了。
最后因为我们钦定的最长的线段位置为零点,其他线段放到正确的位置上的概率还要带上 \(\dfrac{1}{c}\) 的系数。写写就行了。
motivation: ???