(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. N63050 第十六周运维作业

    第十六周 就业和全程班小伙伴本周学习内容: 第三十一天: 高性能服务器nginx 1LVS的跨网段实现 2LVS的防火墙标记和持久连接及高可用实现 3web服务和IO介绍 4IO复用模型 5nginx ...

  2. Ubuntu安装系统监视器system-monitor并显示在状态栏(火狐浏览器)

    system-monitor 使用过Windows 10的朋友们都知道,Windows 10系统自带了一项功能--任务管理器,我们可以通过它方便地查看当前系统的状态,主要包括CPU,内存,硬盘,GPU ...

  3. Android图表控件MPAndroidChart——BarChart实现多列柱状图和LineChart多曲线 (完结)

    首先才接触Android,目前自学一个月,花了一星期,做出了柱状图和曲线图,踩过坑也不少,上代码(主要提供思路,大部分代码可直接用). 参考代码地址:①曲线:https://blog.csdn.net ...

  4. Idea2020.2.3 创建JavaWeb项目(部署Tomcat)方法

    1.创建项目不再是Java Enterprise了,而是先New 一个普通Java项目! 2.创建项目后,选择Run->Edit Configuration->左上角加号->Tomc ...

  5. 新发现的几个不错的c++库

    1.coost 包含了各种常用的库,比boost轻量级的基于c++11的库 https://github.com/idealvin/coost 2.ImGui 一个较少依赖的gui界面库 https: ...

  6. linux下启动rabbitmq,redis,nginx

    这只是其中一种启动方法,也是我自己安装好后试过多次可以用的, 1,启动rabbitmq rabbitmqctl start_app rabbitmq程序端口是5672,可视化界面入口端口是15672, ...

  7. python利用signal自定义函数超时机制

    利用signal模块,可以给函数设置一个超时时间(精确到秒),结合装饰器实现:超时时间内函数运行完成正常退出,超时时间内函数未运行完成则抛出Timeout异常. 1 # coding:utf8 2 i ...

  8. c-->static关键字的使用

    static关键字的使用 static:静态 未使用static 在下列代码中变量a是有生命周期的,调用完后就会被销毁 所以for循环每次调用test函数打印的结果都是2 #include <s ...

  9. react项目--路由封装

    import React, { lazy } from "react"; import Home from "../views/Home"; import Lo ...

  10. 安装kvm后,在windows主机启动virt-manger后报错(no polkit agent available to authenticate action org.libvirt.unix.manage)

    解决方法如下: 1. 增加libvirtd用户组 groupadd  libvirtd 2.在你使用的普通用户界面执行 sudo usermod -a -G libvirtd $USER 3.设置启动 ...