Project Euler 798
Project Euler 798
题目
Card Stacking Game
Two players play a game with a deck of cards which contains \(s\) suits with each suit containing \(n\) cards numbered from \(1\) to \(n\).
Before the game starts, a set of cards (which may be empty) is picked from the deck and placed face-up on the table, with no overlap. These are called the visible cards.
The players then make moves in turn.
A move consists of choosing a card \(X\) from the rest of the deck and placing it face-up on top of a visible card \(Y\), subject to the following restrictions:
- \(X\) and \(Y\) must be the same suit;
- the value of \(X\) must be larger than the value of \(Y\).
The card \(X\) then covers the card \(Y\) and replaces \(Y\) as a visible card.
The player unable to make a valid move loses and play stops.
Let \(C(n, s)\) be the number of different initial sets of cards for which the first player will lose given best play for both players.
For example, \(C(3, 2) = 26\) and \(C(13, 4) \equiv 540318329 \pmod {1\,000\,000\,007}\).
Find \(C(10^7, 10^7)\). Give your answer modulo \(1\,000\,000\,007\).
解决方案
本解决方案参考了Thread中的内容,一开始我是直接暴力加FWT做出本题的。
令\(N=M=10^7\)。每一个花色可以看成是一个局面。整个游戏由多个不同花色组合而成,因此通过SG定理将最终游戏的SG函数值组合出来。由于\(M\)值过大,需要使用快速沃尔什变换解决异或卷积。
那么对于单个花色而言,一共有\(N\)张牌,因此初始状态一共有\(2^N\)种,每种初始状态对应一个\(\{1,2,\dots,N\}\)的子集。
枚举\(2^N\)个子集的\(sg\)函数值并统计个数。那么当\(N=1,2,\dots,14\)时,结果如下(从第\(0\)列起,第\(j\)列表示有多少个子集的\(sg\)函数值为\(j\)):
1 | 2 |
将每一行都逆序,并且最后一个值都减去\(1\),得到
1 | 1 |
对于每一列(除了第\(0\)列)而言,从下面的数开始,都是两两出现,去掉其中一个,那么可以简化成:
1 | (A) |
可以发现,这个三角的产生方式和杨辉三角相同,只是边界值不一样。
舍去第一行,将其右上方进行补全,得到:
1 | 1 2 1 1 1 1 1 1 |
最终发现上面这个图形矩阵可以由杨辉三角的偏移叠加得到:
1 | 1 0 0 0 0 0 0 0 |
总之,\(2^N\)个子集中,\(sg\)函数值为\(k\)的子集个数为\(f\left(N-k-1,\left\lceil\dfrac{k}{2}\right\rceil\right)\),其中\(f(x,y)\)表示三角形数组(A)一开始在第\(x\)列的第一个元素,然后再往下走\(y\)步后的元素。(注意当\(k=0\)时,需要将值添加回\(1\)。)
那么根据刚刚的思想,有
\[f(x,y)=\dbinom{x+y-1}{y}+\sum_{i=0}^x \dbinom{x+y-1}{i}\]
最终,使用等式\(C_i^j=C_{i-1}^{j-1}+C_i^j\)这个等式,在求\(f\left(N-k-1,\left\lceil\dfrac{k}{2}\right\rceil\right)\)时,将求和项的相邻两项合并。并且由于运算\(\lceil\rceil\)运算的存在,合并之后的结果也是连续的,通过这个现象可以\(O(N)\)维护出\(f\left(N-k-1,\left\lceil\dfrac{k}{2}\right\rceil\right)\)的所有值。最终使用快速沃尔什变换计算出最终答案。
代码
本代码参考了Thread中的内容并重新实现。
1 |
|