[CF1528F]AmShZ Farm

题目

传送门 to CF

思路

显然 m o r e − e q u a l \rm more-equal more−equal 就是,不超过 i i i 的数字至少有 i i i 个。

求 b b b 之前,我们先把 a a a 摸清楚。比如说 a a a 序列究竟有多少个呢?

上面那个限制,其实可以转换一下。想想我们怎么求不超过 i i i 的数字?排序之后二分查找嘛。所以我们这里的限制其实就是 a a a 数组排序后第 i i i 个数字不大于 i i i

如果记 ⟨ a i ′ ⟩ \langle a'_i\rangle ⟨ai′​⟩ 为排序后的 a a a 数组,那么 1 ≤ a i ′ ≤ i 1\le a'_i\le i 1≤ai′​≤i 。这像不像很多题目中的 一棵树 的输入方式?即 a i ′ − 1 ∈ [ 0 , i ) a'_i-1\in[0,i) ai′​−1∈[0,i) 作为父节点。显然 0 0 0 是根节点,因为不存在 a 0 ′ a'_0 a0′​ 。

我们将二元组 ⟨ a i , i ⟩ \langle a_i,i\rangle ⟨ai​,i⟩ 拿出来从小到大排序,设 x i x_i xi​ 是第 i i i 小的二元组的下标,即 ⟨ a x i , x i ⟩ \langle a_{x_i},x_i\rangle ⟨axi​​,xi​⟩ 是第 i i i 小的二元组。然后我们可以构建一棵树,点 p p p 的父节点是 x a p − 1 x_{a_p-1} xap​−1​,即排序后的第 a p − 1 a_p-1 ap​−1 个 “下标”,规定第 0 0 0 个是 0 0 0 。

显然它构成一棵树,因为 a x i a_{x_i} axi​​ 就是第 i i i 小的 a a a,第二关键字只是用来保持其稳定性。所以 x i x_i xi​ 会将 x j    ( j < i ) x_j\;(j<i) xj​(j<i) 作为其父节点。

我们很想直接做树计数,所以我们要证明 二者是一一对应的。而排序后的二元组不同,原来的 a a a 序列就不同,因为我们引入了下标作为第二关键字,所以我们只需要知道,给出一棵树,能否唯一确定这些二元组呢?

事实确实如此。也很简单:最小的二元组肯定是 a = 1 a=1 a=1,即根节点 0 0 0 的儿子,记其为 G 0 G_0 G0​ 。它们的顺序是按照编号确定了的。于是我们就得到了前几个二元组。然后次小的就是 a = 2 a=2 a=2,即刚才确定的最小二元组 x 0 ∈ G 0 x_0\in G_0 x0​∈G0​ 的子节点。它们又是按照编号排序。再次小就是 a = 3 a=3 a=3,即 x 1 ∈ G 0 x_1\in G_0 x1​∈G0​,它的子节点按照编号排序……

代码会不会更容易理解?设 c n t [ i ] cnt[i] cnt[i] 初值是深度小于 i i i 的点的数量,设 G [ i ] G[i] G[i] 是 i i i 的所有子节点,那么我们可以还原出 x x x 序列。这里 x 0 x_0 x0​ 将会被赋值为根节点 0 0 0 。

void getX(int now,int dep){
	x[cnt[dep] ++] = now;
	sort(G[now].begin(),G[now].end());
	for(auto y : G[now]) getX(y,dep+1);
}

即,子节点按照编号排序,然后一层一层的放到 x x x 序列里去。显然这是唯一的方案。

所以我们已经可以下结论了。 a a a 序列与一个 n + 1 n+1 n+1 个点的有标号树是对应的。根据 p r u f e r \rm prufer prufer 序列可知 a a a 序列的数量就是 ( n + 1 ) n − 1 (n+1)^{n-1} (n+1)n−1 。

然后来考虑 b b b 。无非就是 a i = v a_i=v ai​=v 的个数为 x x x 时,有 x k x^k xk 的贡献。那么在树中,当 v ≠ 0 v\ne 0 v​=0 时, v v v 有 x x x 个儿子、一个父亲,所以在 p r u f e r \rm prufer prufer 序列中出现 x x x 次;当 v = 0 v=0 v=0 时,则只出现 x − 1 x-1 x−1 次。二者相加即
n ⋅ ( n − 1 x ) n n − 1 − x + ( n − 1 x − 1 ) n n − x = ( n x ) ⋅ n n − x n\cdot{n-1\choose x}n^{n-1-x}+{n-1\choose x-1}n^{n-x}\\ ={n\choose x}\cdot n^{n-x} n⋅(xn−1​)nn−1−x+(x−1n−1​)nn−x=(xn​)⋅nn−x

所以答案就是
∑ x = 1 n ( n x ) ⋅ n n − x ⋅ x k \sum_{x=1}^{n}{n\choose x}\cdot n^{n-x}\cdot x^k x=1∑n​(xn​)⋅nn−x⋅xk

我很认真很认真地思考了一下,为什么这里要把 x k x^k xk 写成 下降幂 呢?但是我始终无法解释。或许真的只能背下来吗?还是说有一种惊人的直觉,仅仅属于拉马努金那样的人,在梦中以神示展现了一切?

众所周知 n m n^m nm 可以利用第二类斯特林数写成下降幂,即
n m = ∑ i = 0 min ⁡ ( m , n ) ( n i ) ⋅ S ( m , i ) ⋅ i ! n^m=\sum_{i=0}^{\min(m,n)}{n\choose i}\cdot S(m,i)\cdot i! nm=i=0∑min(m,n)​(in​)⋅S(m,i)⋅i!

其中 S ( m , i ) S(m,i) S(m,i) 为,把 m m m 个有标号的球放进 i i i 个无标号的盒子,不能空盒,本质不同方案数。组合意义上这个等式是显然的,都代表 m m m 个有标号的球放入 n n n 个有标号的盒子的方案数。利用这个很轻易能得到
a n s = ∑ x = 1 n ( n x ) ⋅ n n − x ∑ i = 0 k ( x i ) ⋅ S ( k , i ) ⋅ i ! = n n ∑ i = 0 k S ( k , i ) ⋅ i ! ⋅ ( n i ) ∑ x = i n ( n − i x − i ) n − x = n n ∑ i = 0 k S ( k , i ) ⋅ i ! ⋅ ( n i ) ⋅ n − i ⋅ ( 1 + n − 1 ) n − i ans=\sum_{x=1}^{n}{n\choose x}\cdot n^{n-x}\sum_{i=0}^{k}{x\choose i}\cdot S(k,i)\cdot i!\\ =n^n\sum_{i=0}^{k}S(k,i)\cdot i!\cdot{n\choose i}\sum_{x=i}^{n}{n-i\choose x-i}n^{-x}\\ =n^n\sum_{i=0}^{k}S(k,i)\cdot i!\cdot {n\choose i}\cdot n^{-i}\cdot (1+n^{-1})^{n-i} ans=x=1∑n​(xn​)⋅nn−xi=0∑k​(ix​)⋅S(k,i)⋅i!=nni=0∑k​S(k,i)⋅i!⋅(in​)x=i∑n​(x−in−i​)n−x=nni=0∑k​S(k,i)⋅i!⋅(in​)⋅n−i⋅(1+n−1)n−i

然后 S ( k , i ) S(k,i) S(k,i) 怎么求呢?它有一个 容斥 的求法,枚举空盒数量,有
S ( k , i ) = 1 i ! ∑ j = 0 i ( − 1 ) j ⋅ ( i j ) ⋅ ( i − j ) k S(k,i)=\frac{1}{i!}\sum_{j=0}^{i}(-1)^{j}\cdot{i\choose j}\cdot(i-j)^{k} S(k,i)=i!1​j=0∑i​(−1)j⋅(ji​)⋅(i−j)k

由于这是卷积(把组合数拆开嘛),可以 O ( k log ⁡ k ) \mathcal O(k\log k) O(klogk) 一次性求出。于是这道题就做完了。

代码

代码就不写了,妹妹的博客里面有。而且她的思路不一样,是官方题解,我觉得根本不可能想到吧……

上一篇:炫技!超酷的HTML 3D动态效果


下一篇:ardunio平衡小车——使用MPU6050模块