1 条题解
-
0
题目理解
给定一个长度为 的序列 ,设 $$S_{i,j} = a_i + a_{i+1} + \dots + a_j$$ 为一段连续子数组的和。
我们需要计算:
$$\text{Ans} = S_{1,1} \oplus S_{1,2} \oplus \dots \oplus S_{1,n} \oplus S_{2,2} \oplus \dots \oplus S_{n,n} $$即所有连续和的异或值。
核心思路
1. 异或运算的性质
异或运算具有按位独立性,即:
$$\text{Ans} = \sum_{k=0}^{\text{maxbit}} \left( \text{第k位为1的连续和个数} \bmod 2 \right) \times 2^k $$因此我们可以按位考虑,对每一位 ,统计有多少个连续和在该位为 ,如果是奇数个,最终答案的这一位就是 。
2. 转化为前缀和问题
设前缀和 ,。
则连续和 (其中 )。
我们要统计对于第 位,有多少对 满足:
即 的第 位为 。
3. 按位统计的方法
对于第 位,设 (低 位全为 )。
将 拆分为高位 和低位 :
- (第 位的值)
- (低 位的值)
那么 的第 位为 的条件,取决于 和 的关系。
情况分析:
-
(高位相同)
- 当 时, 的第 位为
- 因为借位导致高位变化
-
(高位不同)
- 当 时, 的第 位为
- 直接相减高位就为
4. 使用树状数组维护
我们使用两个树状数组:
- :记录 的前缀和的低位 的分布
- :记录 的前缀和的低位 的分布
对于每个 ,根据其 的值,查询对应的树状数组来统计满足条件的 的数量。
代码解析
#include <bits/stdc++.h> #define LL long long using namespace std; const int M = 1e6 + 5, N = 1e5 + 5; #define LB(x) (x&-x) struct BIT { LL t[M]; inline void Clear() { memset(t, 0, sizeof(t)); } inline void Upd(int x) { for (int i = x + 1; i < M; i += LB(i)) t[i]++; } inline LL Qry(int x) { LL S = 0; for (int i = x + 1; i; i -= LB(i)) S += t[i]; return S; } } T[2]; // 两个树状数组,分别对应c=0和c=1的情况 int n; LL S[N], Ans; // S是前缀和数组 int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); cin >> n; // 计算前缀和 for (int i = 1; i <= n; i++) { cin >> S[i]; S[i] += S[i - 1]; } // 按位考虑,最多20位(因为sum <= 1e6 < 2^20) for (int i = 0; i <= 20; i++) { T[0].Clear(), T[1].Clear(); int k = 0; // 统计第i位为1的连续和数量的奇偶性 T[0].Upd(0); // 加入P0 = 0 for (int j = 1; j <= n; j++) { int c = S[j] & (1 << i); // 第i位的值 int A = S[j] & ((1 << i) - 1); // 低i位的值 if (c) { // 当c_j = 1时: // 1. c_i = 1 且 A_j < A_i 的情况 // 2. c_i = 0 且 A_j >= A_i 的情况 k ^= (T[0].Qry(A) + T[1].Qry(M - 5) - T[1].Qry(A)) % 2; } else { // 当c_j = 0时: // 1. c_i = 0 且 A_j < A_i 的情况 // 2. c_i = 1 且 A_j >= A_i 的情况 k ^= (T[1].Qry(A) + T[0].Qry(M - 5) - T[0].Qry(A)) % 2; } T[c > 0].Upd(A); // 将当前前缀和加入对应的树状数组 } if (k) // 如果第i位为1的连续和个数是奇数 Ans += (1 << i); } cout << Ans << endl; return 0; }
关键点说明
1. 树状数组下标处理
代码中
Upd(x)和Qry(x)使用x+1是为了避免 时的死循环。2. 查询逻辑
T[0].Qry(A): 且 的数量T[1].Qry(M-5) - T[1].Qry(A): 且 的数量
3. 奇偶性统计
由于我们只关心数量的奇偶性,所以用
% 2和^=来维护。
复杂度分析
- 时间复杂度:,其中 是值域
- 空间复杂度:
这种方法巧妙地利用了按位独立和树状数组维护低位比较的思想,避免了直接枚举所有连续和的高复杂度。
- 1
信息
- ID
- 5025
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者