石子 [SG函数+倍增优化dp+高精+FWT]

石子

19 7 28



color{blue}{最初想法}

以下 NN 表示 必胜态, PP 表示 必败态,
先考虑一堆石子, 手玩后发现奇数恒为 PP, 偶数恒为 NN,

小证明: 奇数为 2n+12n+1, 由于 =奇*奇=奇, 所以去掉其中一个因子后一定为偶数, 而偶数一定是能够取的, 因为最终状态 11 为奇数 .

然后把 MM 堆石子搞成奇数个偶数即可 .

错的 .


color{red}{正解部分}

经过打表发现 SG(x)=max{i  2iSG(x) = max{i | 2^i|x}x}, 即一个数字的 SGSG 值为这个数字的二进制表示中 2012^{末尾 0 的个数}-1,
相当于 SG(x)=lowbit(x)1SG(x)=lowbit(x)-1 .

可以初步了解到 SG()=0SG(奇数) = 0,

题目转化为: 求出 MMSGSG值 异或起来等于 00 的方案数,


sum[x]sum[x] 表示 SGSG值 等于 xx 的石子数量 种类数, x[1,logn]x∈[1, logn],

sum[0]=n+12sum[0] = lfloor frac{n+1}{2} floor
sum[1]=nsum[0]+12sum[1] = lfloor frac{n-sum[0]+1}{2} floor
sum[2]=nsum[1]+12sum[2] = lfloor frac{n-sum[1]+1}{2} floor
              .              .              . .\ .\ .
sum[n]=nsum[n1]+12sum[n] = lfloor frac{n-sum[n-1]+1}{2} floor

当把一个数列的 二进制表示 全部去掉末尾只有 1100 的数字后,
再将其余数字的二进制末尾减去 1100, 发现剩余的数字又会重新 连续 起来 .
依此得到上式 .


F[i,j]F[i, j] 表示前 ii 堆石子, SGSG 异或起来等于 jj 的方案数,

F[i,j]=F[i1,jk]+sum[k]F[i, j] = F[i-1, j igoplus k] + sum[k]

发现可以使用 倍增 的方式优化,

F[i,j]=F[i1,jk]F[i1,k]F[i, j] = F[i-1, j igoplus k] * F[i-1, k]

时间复杂度 O(logMlog2N)O(logM*log^2N),

得分 50pts50pts .

NNMM 是大数时, 需要先使用 高精度 预处理出所有 sum[]sum[],
然后对于 dpdp 的转移, 发现是异或卷积的形式, 可以用 FWTFWT 优化, 没学过的可以看 这里 .

时间复杂度 O()O(能过) .

得分 100pts100pts .

color{red}{实现部分}

有时间再补 .
咕咕咕 .

原文地址:https://www.cnblogs.com/zbr162/p/11822520.html