ARC137D Prefix XORs 题解

这里的所有下标从 0 开始。

我们考察一下每次操作后的数列 a 会是什么样的。这里用 ai 前面的系数 x 表示 ai 贡献了 x 次,+ 表示异或。

k=0a0a1a2an1k=1a0a0+a1a0+a1+a2(n10)a0+(n20)a1++(00)an1k=2a02a0+a13a0+2a1+a2(n1)a0+(n11)a1++(11)an1k=3a03a0+a16a0+3a1+a2(n+12)a0+(n2)a1++(22)an1k=ma0ma0+a1

可以发现,操作 k 次后,aian1 的贡献系数 x 就是:

(ni+k2k1)

当且仅当 (ni+k2k1) 为奇数的时候,ai 才能对 an1 产生贡献。由 Lucas 定理,这个条件等价于 ni1k1 的按位与是 0。用 U 表示全集,集合运算表示位运算,那么这个条件又等价于 k1U(ni1)。这个玩意就是一个高维后缀和。

时间复杂度 O(nlogn)

#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 1e6, LOGN = 20;
int n, m, a[N + 10], b[1 << LOGN];
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
scanf("%d", a + i);
int all = (1 << LOGN) - 1;
for (int i = 0; i < n; i++)
b[all ^ (n - i - 1)] = a[i];
for (int i = 0; i < LOGN; i++)
for (int msk = 0; msk < (1 << LOGN); msk++)
if (!((msk >> i) & 1)) b[msk] ^= b[msk ^ (1 << i)];
for (int i = 0; i < m; i++)
printf("%d%c", b[i], " \n"[i == m - 1]);
return 0;
}
posted @   registerGen  阅读(19)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示