[CTS2019]氪金手游 [* easy]
给定一棵大小为 (N) 的有向树,每个点的点权 (W_i) 都有概率为 (1,2,3)(给定分布概率)
每次会随机抽到一个点,概率为 (frac{W_i}{sum W}),我们会这样一直 D 直到所有卡都被得到。
对于每个点记 (T_i) 为其第一次被选中的概率,如果对于每条边 ((u,v)),均有 (T_u<T_v),则称小 A win。
求小 A win 的概率。
(Nle 1000)
Solution
和不等关系一模一样。
首先,我们可以轻易的解决外向树的情况(当然,想到先处理这个特殊情况我觉得是这道题最难的部分),对于有向树,我们将每条边视为 (0/1),假定忽略掉其内向边,可以理解为对 (2^n) 的 01 串求了高维后缀和,为此只需要容斥即可
于是我们统计 (sum (-1)^{|S|-t}W(S)),其中 (S) 为一个边子集,满足其包含原树上的所有外向边。
显然不连通的部分可以直接乘法原理,联通的树只需要 care (W) 的和即可解决(只需要保证 (i) 在所有子连通块中第一个出现,此概率为 (frac{W_1}{sum W_i}))
最后,使用 dp 来统计这个容斥即可,复杂度 (mathcal O((nk)^2)),其中 (k) 为 (W) 的最大值。
[CTS2019]随机立方体 [* easy]
给定 (n,m,l,k),表示一个大小为 (n imes m imes l) 的立方体,将 (1sim n imes m imes l) 这些数随机填入这个立方体中,对于一个格子,若这个格子上的数比三维坐标至少有一维相同的其他格子上的数都要大的话,我们就称它是极大的。
求极大格子数恰好为 (k) 的概率,答案对 (998244353) 取模。
(n,m,lle 5cdot 10^6,kle 100,Tle 10)
Solution
先考虑计数。
不难发现:
-
极大的点数至多是 (min(n,m,l)) 的。
-
每个极大的点会限制三个面。
-
极大的点的坐标具体是多少不影响方案数。
恰好不好求,考虑容斥,设 (g_k) 表示至少有 (k) 个点极大的答案。
假设得到了 (g_{k,k+1sim min(n,m,l)}) 那么根据二项式反演,我们有:
接下来考虑至少 (k) 个点极大的方案如何求。
答案可以分成两个部分,选择了 (k) 个点的情况下的答案,给这 (k) 个无标号的点分配坐标的方案数。
Part1
考虑分配坐标的方案数。
可以视为给 (x,y,z) 三个维度分别选出 (3) 个集合,在将 (3) 个集合的元素进行组合的方案数。
不难发现是 (frac{inom{n}{k}inom{m}{k}inom{l}{k}(k!)^3}{k!}),请注意元素无序。
Part2
考虑选择了 (k) 个点的情况下的答案。
考虑到点的位置没有影响,为了简化问题,我们考虑将点具体为 ((1,1,1),(2,2,2)...(k,k,k))
问题等价于满足这些元素比被他们约束的元素的权值大的方案数。
显然问题可以转换为序列计数,考虑长度为 (n imes m imes l) 的序列,这些元素必须在被他们约束的元素之后出现的方案数。
考虑每个点约束的三个面,实际上存在交点/交线等部分,直接统计不好考虑。
注意到每个点是平等的/等价的,那么对于某个序列,这 (k) 个点本身必然存在一种顺序关系,同时每种顺序关系的答案是相同的。
所以考虑钦定 ((1,1,1)) 为序列中第一个出现的,((2,2,2)) 为序列中第 (2) 个出现的...
将这个情况下的答案乘以 (k!) 即可(表示任何一种排列的答案相同)。
那么此时 (1) 排在序列中最前面,所以一旦一个元素被 (1) 约束,他必然要排在 (1) 前面,即所有点中满足存在一个维度为 (1) 的点的数量。
对于 (2) 而言,他约束的点的数量为所有点中满足坐标均大于 (2) 的点中存在一个维度为 (2) 的点的数量,相当于 (n,m,l) 均减少 (1) 的情况。
考虑恰好有一个维度是 (1) 的点的数量,大概是这个:
- 请注意这些元素是有区别的。
设这些值分别为 (f_1,f_2...f_k),其前缀和加 (k) 的和为 (S_1,S_2...S_k) 那么答案为:
即:
由于要乘以 (frac{1}{(nml)!}),所以这一部分消去了。
最终的答案就是:
即:
问题在于求逆元,这个可以线性求逆元,just a trick
然后这道题就做完了。
复杂度 (mathcal O(Tcdot min(n,m,l)+max(n,m,l)))
[CTS2019]重复
给定 (m) 和字符串 (s),称一个小写字符串 (t) 是合法的,当且仅当其长度为 (m),其进行无限次循环后存在一个字串满足其长度和 (s) 相同,且字典序小于 (t)
其中 (n) 为 (s) 的长度,(m) 为小写字符串 (t) 的长度。
则,(n,mle 2000)
Solution
考虑对于字符串 (s),其中,位置 (i) 是无用的,当且仅当存在一个前缀 (s[l...i]) 满足 (s[l...i]) 小于对应长度的字符串的前缀。
我们找到最小的 (i) 并只考虑 (s[1...i-1]),显然为这个串计算答案与原问题等价,设这个串为 (s')。
我们先基于判定性的角度,考虑串 (t^{infty}),我们从前往后匹配 (s') 的时候必然会使得其匹配一个尽可能长的后缀(考虑 (s') 的构成),此时加入任意一个字符,当满足 (t<s_{i+1}) 的时候,必然得到了一个合法的串,否则 (t=s_{i+1}) 将继续匹配,对于 (t>s_{i+1}),显然会引回起点。
这是因为假定 (t>s_{i+1}) 没有引回起点,则必然存在 (s[1...j]) 满足其与 (s[pre...i]+t) 相同,于是此时 (s[pre..i]+s_{i+1}) 小于此前缀,我们会删去 (i+1)
唯一的例外是 (s_{end}),在其后面加入字符串可能会导向之前的匹配状态 (u),然而显然 (u) 唯一且满足我们之前的约束。
设 (t^{infty}) 对应的节点为 (u),则应当有 (t^{infty}+t=t^{infty}),于是从 (u) 出发走 (m) 位应当能够走回自己。
同时,满足此约束的 (u) 会恰好对应着 (t^{infty}),这是因为考虑到任意的前缀 (mathbf{t}) 经过若干轮 (t) 之后必然会到达一个稳定的位置,此时即为 (t^{infty})(相当于 (mathbf{t}+t^{infty}) 在自动机上匹配的最长后缀,这显然对应相同,唯一的节点)
于是我们只需要考虑从 (u) 出发,经过 (m) 条边,回到 (u) 的方案数,此时可以得到 (mathcal O(n^2m)) 的做法。
然而由于自动机的结构过于简单,我们不难发现对于任意的 (u),其不指向根节点的出边是唯一的,除去 (s_{end}) 之外,每个点可能走出来的环必然经过根节点,我们可以枚举其走了多少条边后到达根节点,预处理 (f_{i,j}) 表示根节点走了 (i) 步到达了 (j) 的方案数即可。
对于 (s_{end}),我们额外特判其唯一的,可能的不经过根节点的环是否存在即可,复杂度 (mathcal O(nm))
事实上,这个自动机的结构足够简单,所以应该是还可以继续优化的。
最后一个问题,如何确定 (s') ?我们使用 kmp 求出 next 的数组,因为对于 (s') 的所有前缀均满足约束,其所有前缀均小于其等长的区间,于是 (i) 的一个前缀 ([j...i-1]) 必然大于对应的前缀,此时加入 (i) 也不可能成为答案,唯一的反例是 ([j...i-1]) 与前缀相同的情况,此时加入 (s_{i}) 可能会小于,若小于,则 (i) 显然非法,否则大于,则我们跳 next,若等于,显然可以规约为子问题,同时这个 ([j...i]) 为其对应的 next 数组。复杂度 (mathcal O(n))
[CTS2019]珍珠
给定 (n,m,D),计算有多少个长度为 (n) 的序列,每个元素的值为 ([1,D]),满足出现次数为奇数的颜色数小于 (n-2m) 的序列的数量。
(n,mle 10^9,Dle 10^5)
Solution
Algorithm1
- 容斥
设 (f_i) 表示单子数量恰好为 (i) 的序列的数量。
设 (g_i) 表示单子数量至少为 (i) 的序列的数量。
根据容斥理论,我们有:
于是有:
于是执行一次差值卷积即可。
考虑 (g_i),不难注意到:
可以卷积了。复杂度 (mathcal O(nlog n))
Algorithm2
(mleftarrow n-2m),这样我们的表述将更为简洁。
考虑通过生成函数将答案直接写出来,我们有:
接下来考虑 (inom{D}{k}inom{k}{i}inom{D-k}{j}) 的组合意义。
等价于从 (D) 个球选 (k) 个再选 (i) 个,再从剩下的 (D-k) 个选 (j) 个的方案数。
也等价于先选 (i+j) 个出来,再选 (i) 个出来,剩下的归为 (j),再从 (D-(i+j)) 个中选 (k-i) 个出来。
于是有 (inom{D}{k}inom{k}{i}inom{D-k}{j}=inom{D}{i+j}inom{i+j}{i}inom{D-i-j}{k-i})
枚举 (i+j=t),回代得到:
考虑后面的组合数的组合意义,等价于从 ((0,0)) 出发走到 ((j,i)),再走到 ((D-k,k)) 处的方案数。
这样可以考虑通过生成函数来解决路径计数的问题,具体的,我们先会行走 (t) 步,每一步的贡献都是 (1),接下来我们走 (D-t) 步,每次走 (y) 贡献均为 (-1)
于是得到:
考虑设 (F(t,D)=sum_k^m (1+x)^t(1-x)^{D-t}[x^k])
我们发现 (F(0,d)=sum_k^m(1-x)^{d}[x^k]=sum_k^m inom{d}{k}(-1)^k)
通过手玩/人类智慧极限,我们发现 (F(0,0)=1,F(0,d)=(-1)^minom{d-1}{m})
具体论证可以通过帕斯卡定理来说明。
接下来我们进一步打表+手玩,发现 (F(x,y)=2F(x-1,y-1)-F(x-1,y))
知道结论后论证其正确性是 naive 的,但是正向推导是困难的,所以还是建议打表找规律。
不过事实上在计算 (F(1,6),F(2,6)...) 这些值的时候其实就可以看出来了。
那么设 (G_t(x)=sum_k F(t,k)x^k),不难发现 (G_t(x)=G_{t-1}(x)(2x-1))
于是我们有:
其中,(G_0(x)) 是可以预处理的,设第 (i) 项系数为 (g_i)。
于是我们有:
一次 NTT 即可,复杂度 (mathcal O(nlog n))
我的实现不是很精细,大概是 (mathcal O(nlog P)) 的。