Solution -「SDOI2019」移动金币

cirnovsky /

对 @command_block 没有 implementation 做法的细化。理论来说可以通过,但因为我实现得较劣无法通过。:(

把金币中的空隙看作石子,就是一个阶梯 Nim 的模型(有总共 nmn-m 个石子,m+1m+1 个石堆,其中最左边有一个独立的石堆)。于是问题转化为满足偶数编号的石堆石子数异或和非零的初始方案数。

取补集后可以给出这样一个 DP:令 f(k,i,j,v{0,1})f(k,i,j,v\in\{0,1\}) 表示考虑第 kk 个二进制位,决策好了 ii 个石堆,恰好 jj 个石子被分配,当前填 00 / 11 的方案数。

转移,考虑根据 kk 来分层,然后每个层独立地转移,最后来合并。具体来说,f(k,i,j,v)f(k,i+1,j,v)f(k,i,j,v)\rightarrow f(k,i+1,j,v),并且 f(k,i,j,v)f(k,i+1,j+2k,v[i+10(mod2)])f(k,i,j,v)\rightarrow f(k,i+1,j+2^k,v\oplus[i+1\equiv0\pmod2]),即考虑填 00 还是 11。令第 kk 层合并后的结果为 s(k,i,j,v)s(k,i,j,v),最后的答案即 (nm)s(log2ai,m+1,nm,0)\binom{n}{m}-s(\lfloor\log_2a_i\rfloor,m+1,n-m,0)。合并的过程是 s(k,m+1,j,0)=if(k,m+1,i,0)×s(k1,m+1,j,0)s(k,m+1,j,0)=\sum\limits_i f(k,m+1,i,0)\times s(k-1,m+1,j,0)

边界即 f(k,0,0,0)=1,s(0,m+1,j,0)=f(0,m+1,j,0)f(k,0,0,0)=1,s(0,m+1,j,0)=f(0,m+1,j,0)

时间复杂度 Θ(nmlog2n)\Theta(nm\log_2n)这是一份比较朴素的实现方法,可以帮助理解,并不能通过此题。

然后你会发现可能由于内存访问不连续等原因,朴素的实现并不能通过此题较大的数据。

考虑交换数组顺序,利用分奇偶讨论转移的特殊性来乘一个 12\frac{1}{2} 的常数等方法卡常,有效,但不完全有效。

但是确实过不去,希望哪天来个卡常大师给卡进去。(