题解 CF1713F【Lost Array】

先考虑第 0 行到第 n 列是怎么推的?

首先,为了方便将第 0 行的数从右往左重标号为 0,1,,n1。我们发现 (0,i) 对于 (j,n) 的贡献是 C(i+j,i)(mod2),根据 lucas 定理可得有贡献当且仅当 i and j=0

考虑容斥,枚举 k,钦定 i and j 在二进制下为 k 的超集,则 (0,i)(j,n) 被贡献次数为 2popcount(i and j)。于是,直接异或即可。

所以,我们先考虑求出 ti 表示 i 为超集的数的异或和(ta0,i 的高维后缀异或和)。

考虑枚举 i and j=k,于是,aj,n 的值即为 kjntkaj,nti 的高维前缀异或和)。

综上,我们发现,从第 0 行推到第 n 列是对 a0,i 先做一遍高维后缀异或和,再做一遍高维前缀异或和。

考虑从第 n 列如何反推第 0 行?

直接倒过来做,先对 an,j 做一遍高维前缀差分异或和,再做一遍高维后缀差分异或和。(因为是在异或运算下,所以前缀和和前缀差分、后缀和和后缀差分都分别是一个东西)。

Copy
const int N = 5e5 + 10; int a[N]; signed main() { int n; read(n); for (int i = 0; i < n; ++i) read(a[i]); int lg = log2(n); F(i, 0, lg) for (int j = 0; j < n; ++j) if ((j >> i) & 1) a[j] ^= a[j - (1 << i)]; F(i, 0, lg) for (int j = 0; j < n; ++j) if ((j >> i) & 1) a[j - (1 << i)] ^= a[j]; for (int i = n - 1; ~i; --i) writes(a[i]); return 0; }
posted @   zhaohaikun  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示