(CF1761D Tester Solution in Chinese)

定义 \(L(v)=\log_2\operatorname{lowbit}(v+1)\);也就是说,\(L(v)\) 是 \(v\) 在二进制下末位 \(1\) 的个数。

例如,\(L((1011)_2)=2,L((11100100111)_2)=3\)。

然后定义

\[C(n,k,l)=\sum_{i=0}^{2^n−1}\sum_{j=0}^{2^n−1}[f(i,j)=k,L(i+j)=l]
\]

则,答案可以被描述为

\[S(n,k)=\sum_{l=0}^nC(n,k,l)
\]

考虑对其做递推。

通过对 \(i,j\) 末位做分类讨论,容易得到

\[C(n,k,l)=\begin{cases}1&n=0\\2C(n-1,k,l-1)&l>0\\\sum_pC(n-1,k,p)+\sum_pC(n-1,k-p-1,p)&\text{otherwise.}\end{cases}
\]

而这立刻给出

\[C(n,k,l)=\begin{cases}1&n=0\\2^lC(n-l,k,0)&l>0\\\sum_p2^pC(n-p-1,k,0)+\sum_p2^pC(n-p-1,k-p-1,0)&\text{otherwise.}\end{cases}
\]
\[Ans_{n,k}=\sum_{l=0}^n2^lC(n-l,k,0)
\]

也就是说,我们只用去研究 \(C(n,k,0)\),就可以获得答案了!

于是对其,我们定义一个 BGF(二元生成函数)

\[F(z,u)=\sum_n\sum_kC(n,k,0)z^nu^k
\]

然后就得到

\[F=1+F\times\sum_p\left(2^pz^{p+1}+2^pz^{p+1}u^{p+1}\right)
\]
\[F=1+F\times(\frac z{1-2z}+\frac{zu}{1-2zu})
\]
\[F=\frac1{1-(\frac z{1-2z}+\frac{zu}{1-2zu})}
\]
\[F=\frac{(1-2z)(1-2zu)}{1-3z-3zu+8z^2u}
\]

这样,我们的答案就是

\[S(n,k)=[z^nu^k]\frac F{1-2z}=[z^nu^k]\frac{1-2zu}{1-3z-3zu+8z^2u}
\]

考虑如何计算 \(S(n,k)\)。

\[S(n,k)=[z^nu^k]\frac{1-2zu}{1-3z-3zu+8z^2u}\\=[z^nu^k]\frac1{1-3z-3zu+8z^2u}-2[z^{n-1}u^{k-1}]\frac1{1-3z-3zu+8z^2u}
\]

这两部分是类似的,现在我们就考虑第一部分(为了减少手算量)。我们仅仅观察第一部分好了。

不妨称之为 \(A_n\)。

\[A_n=[z^nu^k]\frac1{1-3z-3zu+8z^2u}=[z^{n-k}]\frac{(3-8z)^k}{(1-3z)^{k+1}}
\]

考虑使用 ODE 来计算所有 \(A_n\)。

\[G(z)=\frac{(3-8z)^k}{(1-3z)^{k+1}}
\]
\[G_t=[z^t]G
\]

\[G'=\frac{-8k(3-8z)^{k-1}(1-3z)+3(k+1)(3-8z)^k}{(1-3z)^{k+2}}
\]

于是

\[(1-3z)(3-8z)G'=\frac{-8k(3-8z)^k(1-3z)+3(k+1)(3-8z)^{k+1}}{(1-3z)^{k+1}}\\=(-8k(1-3z)+3(k+1)(3-8z))G
\]

\[(3-17z+24z^2)G'=(k+9-24z)G
\]
\[3(t+1)G_{t+1}-17tG_t+24(t-1)G_{t-1}=(k+9)G_t-24G_{t-1}
\]

从而

\[G_{t+1}=\frac{(9+17t+k)G_t-24tG_{t-1}}{3(t+1)}
\]

考虑边界,也就是

\[G_0=3^k,G_1=3^{k-1}(9+k)
\]

于是我们就可以在 \(O(n)\) 时间内计算出数列 \(G\) 了。

事实上,如果模数为 \(998244353\),我们还可以用整式递推在 \(O(\sqrt n\log n)\) 时间内求出单项 \(S(n,k)\)。

参考代码

loj6851的更多相关文章

随机推荐

  1. TensorFlow中的Placeholder

    简单运用 这一次我们会讲到 Tensorflow 中的 placeholder , placeholder 是 Tensorflow 中的占位符,暂时储存变量. Tensorflow 如果想要从外部传 ...

  2. 对象可能是类数组对象 不具备数组的原型内的方法 所以可以用call或者apply把this指向改成数组或对象原型

    const arr = [] 2Object.prototype.toString.call(arr) === '[object Array]' // true 3 4 const obj = {} ...

  3. JavaSE——==与.equal()方法

    ==号的作用 比较基本数据类型:比较的是具体的值 比较引用数据类型:比较的是对象地址值 package com.zhao.stringdemo; public class StringDemo2 { ...

  4. 《CSOL大灾变》开发记录——武器购买逻辑开发

    上次完成了武器购买界面设计,这次来完成武器购买逻辑与武器选择逻辑. 武器购买逻辑分为两个部分,一个部分是GUI部分的逻辑,也就是购买菜单,一个是武器游戏数据更新的逻辑,也就是实际中玩家获取武器的逻辑开 ...

  5. idea 使用JRebel 报1099错误

    idea 使用JRebel 报1099错误 以为是端口占用 后面搜了一下 发现是编码问题 windows用户名是中文名 添加以下代码即可 -Dfile.encoding=UTF-8 -Djava.aw ...

  6. 谷歌浏览器上elementUI的按钮文字消失了

    解决方案:有个谷歌浏览器插件,好像是什么淘宝的,删掉即可

  7. Apache和Nginx设置伪静态(URL Rewrite)的方法

    在Apache中有两种方法配置,一是通过httpd.conf文件,二是通过.htaccess文件. 使用 httpd.conf 来配置 rewrite 策略. 要使用 httpd.conf 文件来设置 ...

  8. notepad++解决粘贴复制代码行数问题

    一.打开 Notepad++,按住 Alt,鼠标点击拖出选择框,这个是列选方法.如图: 然后删除即可 二. 1.将带行数的代码粘贴复制到notepad++中: 2.按ctrl+f,选中替换,选中正则表 ...

  9. 25 String 对象中的属性

    <!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF ...

  10. Object.assign() 方法浅析

    Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. const target = { a: 1, b: 2 ,c:3,e:6}; cons ...