正睿十连测 Round 8 补题记录。 菜到去世……
陈太阳的石子游戏
有
n
堆石子,每堆石子被染成了黑色或者白色,第
i
堆石子有
ai
个石子。陈太阳和杨主力轮流操作,杨主力先操作。操作有两种,他们每次可以选择一种进行操作:
- 从石子数量最少的黑堆中取出任意正整数数量的石头
- 从任何白堆中取出任意正整数数量的石头
不能操作的玩家将会输掉游戏。现在所有石头堆都是固定的,但尚未着色。
陈太阳贿赂了裁判,使他有机会自己给所有石头涂色。
现在,他想知道有多少种涂色方法使得自己能赢下游戏?
由于答案可能太大,因此只需要输出模
1000000007
答案即可。
n≤106
好吧 - -这才明白什么叫做 SG
函数。
Sprague-Grundy(SG)定理
对于一个完整的游戏局面
G
,有若干个子游戏
G0,G1,G2,⋯
那么:
SG(G)=⨁Gi
对于一个局面
x
,若其有若干个后继局面,则:
SG(x)=mex{SG(y)∣y是x后继}
特殊地,若一个局面
P
没有后继局面,则其
SG
值为
0。
首先考虑必胜局面条件是什么:
对一个局面划分子游戏,显然,白色石头和黑色石头可以作为两个子游戏,白色石头构成一个经典的
Nim
游戏。只需要考虑黑色石头的
SG
值即可。
通过手算不难发现黑色石头的
SG
值为:
最小堆中的石头数−(最小堆的数量+[所有黑色石头堆都具有相同的大小])%2
先按照石子数量排序。
可以考虑枚举最小堆出现次数和石子数量
x,石子数量小于
x
的石子堆一定是白色堆,枚举一个出现次数,可以算出石子数量等于
x
和小于
x
的堆的
SG
值
z,然后考虑后面的石子堆有多少种选法,使得其
SG
值等于
z
即可。这个问题是 线性基
的经典问题。
陈阳太的集合
陈阳太有个集合
U={1,2,3,⋯,n}
她打算和杨主力轮流操作。
- 陈阳太负责一次拆分操作。具体地,陈阳太会将集合
U
分成至少两个非空集合,它们的并集为
U
且两两交集均为
∅。
- 杨主力负责多次合并操作。具体地,杨主力首先收到陈阳太操作后的所有集合,随后每当杨主力手上存有多于一个集合,则必须取出两个集合合二为一,即取出的集合消失并获得它们的并集。
显然最终杨主力将获得集合
U,同时操作结束。
定义两局操作不同,当且仅当存在集合
S,在一局操作中出现过且在另一局操作中从未出现。注意,与操作次序无关。
求杨主力和陈阳太一共有多少局不同的操作,对 NTT
质数取模。
n≤106
只考虑如何合并一些集合,可以倒过来考虑,考虑一开始有一个全集
U
,如何拆分成若干个子集,显然每一种拆分方式对应一个操作等价类。
考虑递推式:
设
f(n)
为将元素个数为
n
的集合拆分成若干个集合的情况。
易知递推式为:
f(n)=1+21i=1∑n−1(in)f(i)f(n−i)
其中
+1
是考虑到这个集合就在这里停止划分,后面的
21
是因为划分没有什么顺序性。
可以考虑生成函数优化,这个式子后面的项稍微补补就是一个卷积,先定义
f(0)=1,可以把式子写成:
f(n)=1+21[(i=0∑n(in)f(i)(n−i))−2×f(n)]
2f(n)=1+21i=0∑n(in)f(i)(n−i)
补齐常数项:
2f(n)=1+2[n=0]+21i=0∑n(in)f(i)(n−i)
有组合数,考虑指数生成函数:
2n!f(n)=n!1+2[n=0]+21i=0∑ni!f(i)(n−i)!f(n−i)
设
F(x)=∑i≥0f(i)i!xi
2F(x)=ex+21+21F2(x)
解出
F(x)
根据常数项,得到最终取值为:
F(x)=2+3+2ex
需要一个多项式开方。大佬们对长度为
106
的多项式开方都冲到
500ms
了,我的甚至需要跑
8s
左右,就很震撼 /kk。
题目关键是对计数对象的转化,需要根据题目描述的等价类划分方式,确定转化为何种计数对象。
陈太阳的树
陈太阳有一棵
n
个点的树,每条边
ei
上有一个非空字母集合
Si⊂{′a′,′b′,⋯,′z′},陈太阳还有一个模板串集合
T={t1,t2,⋯,tm}
杨主力给了陈太阳
q
次询问,每次询问给定一条从
u
到
v
的有向树链,问有多少种在树边上选字母的方案,使得将所有树链上的字母按照从
u
到
v
的顺序写出来之后形成的字符串包含模板串集合中至少一个模板串。
杨主力不想让答案数字太大,于是陈太阳只需要告诉杨主力对 998244353
取模的结果就好了。
输入第一行两个正整数
n,m,q,分别表示树的大小,模板串集合的大小以及询问的个数。
接下来
n−1
行,每行两个正整数
u,v(1≤u<v≤n)
以及一个字符串
s,表示
u
点到
v
点之间有一条边,边上的非空字母集合由
s
中的所有字母构成。保证
s
只包含小写字母且不包含重复的字符
接下来
m
行,每行一个字符串,表示一个模板串。保证所有模板串的长度之和不超过
40
接下来
q
行,每行两个正整数
u,v(1≤u,v≤n,u=v),表示一次询问。
1≤n≤2500,1≤q≤5000,1≤m≤40,∑∣ti∣≤40
多模板匹配问题,显然需要 AC 自动机,显然可以在 AC 自动机上对路径
dp。
一个 AC 自动机的技巧:如果只是想判断 AC
自动机中是否存在一个模板串可以在文本串中完全匹配,可以考虑强制将 AC
自动机中每一个模板串结束字符对应结点的出边全都连向自己。最后走完文本串后一定会停留在一个模板串结尾的对应结点。
但是这里的文本串不确定,就可以考虑在 AC 自动机上 dp。
设
dp[n][u]
表示考虑了路径的前
n
个结点,到达结点
u
的路径个数。
如果每次暴力 dp 就能够得到
O(qnt3)
的做法。
考虑到每个边的转移其实是相似的,按照动态 dp
的套路可以把每一条树边的贡献理解为一种线性变换?考虑使用矩阵乘法表示转移,每一条树边就对应一个矩阵,可以倍增预处理就能够做到单次询问
O(t2logn)
的复杂度。
可以考虑树剖然后线段树维护矩阵乘积。
还可以点分之后预处理每个点到其祖先路径上的矩阵乘积,然后点分树上合并矩阵乘法。
还可以点分之后离线处理每个询问。
能过几个就不得而知了