「codeforces - 1408I」Bitwise Magic

link。


l=log2k,在本题中你可以粗暴地认为 l=4

对于某一个 x 而言,x0,x1,,xk 有极强的相关性,具体而言有以下两种情况:

(1)x 二进制下末 lk,此时 x0xk 除了末 l 位全部相同。

提前给答案异或上 xl 位以外的位(这些位始终不变),不难发现 x 有效部分其实只有末 l 位。

(2)x 二进制下末 l<k,此时取 x 除末 l 位以外的最低非零位 p

那么 x0xk 除了末 l 位,末 l+1p 位一定形如 0...011...10,其他位始终相同。

一样可以发现 x 有效部分仅取决于末 l 位与 p

这导出一个重要的事实:本质不同的 x 只有 O(c2l)=O(ck) 种。

p.s.:我们稍后将会看到,这里的分析其实还导出了另一个非常重要的事实。


我们记 F(y,s) 这个二元 GF,其中 y 是 EGF,s 是集合幂级数,第 yisj 项对应系数含义为 “选 i 个数异或和为 j 的方案数”。

容易发现,题目本身就是求 n 个形如 (i=0kyii!sxi) 的二元 GF 的卷积。

由于我们将本质相同的 x 放在了一起,问题变成求 O(ck) 个形如 (i=0kyii!sxi)t 的卷积。

s 视作主元做 fwt,只需要分别将每一位所有的 (i=0kaiyi)t 卷起来,最后取第 k 项并 ifwt 回去即可得到答案。

注意到项数只有 O(k) 项,可以考虑做 O(k2) 的 ln + exp 优化求 t 次幂的过程。由于始终是做卷积,可以在 ifwt 之前再 exp。

O(ck) 个 GF 做 fwt 的复杂度为 O(ck×c2c×k)(注意我们的对象是 O(k) 的多项式);

O(ck) 个 fwt 后的每个多项式做 ln 的总复杂度为 O(ck×2c×k2)(求 ln 时需要常数项为 1,注意处理符号)

合并只需要对应位相加,复杂度为 O(2c×ck×k)

最后 exp 的总复杂度为 O(2c×k2)

最后 ifwt 的复杂度为 O(c2c)

由此,我们得到一个 O((c+k)ck22c) 的朴素实现。


一个简单的观察:(i=0kyii!sxi) 项数很少。考虑从此入手优化。

直接用定义做 fwt 可以做到 O(ck×k2c)

依照 fwt 的定义,最后求 ln 的多项式一定形如 1+(i=1k±yii!),一共只会有 O(2k) 种可能性,因此做个 O(2k×k2) 的预处理即可。

这样可以将其优化到 O(ck22c)


回到一开始的性质。

情况(1)只有末 l 项,这意味着 fwt 之后的结果本质只有 2l 个不同的位

情况(2)虽然可能会有 p 位发生改变,但它的信息量只有 l+1 位(其中一个信息为 “l+1p0...01 还是 1...10”),所以类似的有 fwt 之后的结果本质只有 2l+1 个不同的位

严格来说,fwt 之后的结果只跟它们张成的线性空间维数有关。

这意味着我们可以将 O(2c) 的 fwt 缩成 O(2l)=O(k) 的 fwt(也没有预处理 ln 的必要了)。

如果不预处理 ln,则 fwt + ln 这两部分的复杂度降到 O(ck×2l×k2)=O(ck4)

然而合并还是 O(2c×ck×k) 的复杂度,依然考虑把 O(2c) 降到 O(2l)

把情况(1)中的所有多项式,与情况(2)中 p 相同的所有多项式先合并,复杂度变为 O(2c×c×k+2l×ck×k)

那么,最终的总复杂度为 O(c(c+k)2c+ck4)

参考实现:https://codeforces.com/contest/1408/submission/114282085


我并不太清楚异或卷积能否使用 ln + exp 优化幂运算,感觉不太懂,总之先跑路了。

希望有懂哥能教教我.jpg。

posted @   Tiw_Air_OAO  阅读(148)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示