前缀和与差分
前缀和与差分
前缀和;差分。
概念
前缀和预处理后,可在 O(1) 时间求任意区间 [l,r] 的和(或积、异或等可结合运算的和)。一维数组最常见:s[i]=s[i-1]+a[i],区间和 s[r]-s[l-1]。差分是前缀和的逆操作:对原数组做区间加,只需在差分数组两端 +v、-v,再前缀还原。与 cspj.algo.dp-basic 区分:前缀和/差分是静态或离线区间统计工具,不是一般最优子结构;与 cspj.algo.enumerate-simulate 区分:有了前缀和就不应对每次查询暴力扫区间。CSP-J 复赛可能把前缀思想放在异或、模意义或「选不相交区间」的建模里。
CSP-J 常考
目前语料只有 1 道:
cspj-r2-2025第 3 题:复赛编程,区间异或和转化为前缀异或差,再在不重叠区间上选型。
// 一维前缀和:O(n) 预处理,O(1) 区间求和
int a[100], s[100], n;
s[0] = 0;
for (int i = 1; i <= n; ++i)
s[i] = s[i-1] + a[i];
// [l,r] 的和(1-indexed):
int sum = s[r] - s[l-1];
// 差分:给 [l,r] 每个数 +v
int d[100];
d[l] += v; d[r+1] -= v;
// 还原:for i: a[i]=a[i-1]+d[i]
易错点
- 下标 0 与 1:
s[0]=0是为了让s[r]-s[l-1]在 l=1 时成立,阅读程序 trace 时不要漏这一位。 - 前缀异或与前缀和混淆:异或满足「相同抵消」,区间异或同样是前缀异或的差。
- 差分还原时忘记对
d[r+1]减 v,导致后缀全部被加 v。
异或和
C++时间 1 s内存 512 MB 文件 IO:xor.in → xor.out
小 R 有一个长度为 n 的非负整数序列 a1,a2,…,an。定义一个区间 [l,r] (1≤l≤r≤n) 的权值为 al,al+1,…,ar 的二进制按位异或和,即 al⊕al+1⊕⋯⊕ar,其中 ⊕ 表示二进制按位异或。
小 X 给了小 R 一个非负整数 k。小 X 希望小 R 选择序列中尽可能多的不相交的区间,使得每个区间的权值均为 k。两个区间 [l1,r1],[l2,r2] 相交当且仅当两个区间同时包含至少一个相同的下标,即存在 1≤i≤n 使得 l1≤i≤r1 且 l2≤i≤r2。
例如,对于序列 [2,1,0,3],若 k=2,则小 R 可以选择区间 [1,1] 和区间 [2,4],权值分别为 2 和 1⊕0⊕3=2;若 k=3,则小 R 可以选择区间 [1,2] 和区间 [4,4],权值分别为 1⊕2=3 和 3。
你需要帮助小 R 求出他能选出的区间数量的最大值。
输入格式
从文件 xor.in 中读入数据。
输入的第一行包含两个非负整数 n,k,分别表示小 R 的序列长度和小 X 给小 R 的非负整数。
输入的第二行包含 n 个非负整数 a1,a2,…,an,表示小 R 的序列。
输出格式
输出到文件 xor.out 中。
输出一行一个非负整数,表示小 R 能选出的区间数量的最大值。
样例
4 2 2 1 0 3
2
小 R 可以选择区间 [1,1] 和区间 [2,4],异或和分别为 2 和 1⊕0⊕3=2。可以证明,小 R 能选出的区间数量的最大值为 2。
4 3 2 1 0 3
2
小 R 可以选择区间 [1,2] 和区间 [4,4],异或和分别为 1⊕2=3 和 3。可以证明,小 R 能选出的区间数量的最大值为 2。
4 0 2 1 0 3
1
小 R 可以选择区间 [3,3],异或和为 0。可以证明,小 R 能选出的区间数量的最大值为 1。注意:小 R 不能同时选择区间 [3,3] 和区间 [1,4],因为这两个区间同时包含下标 3。
数据范围
对于所有测试数据,保证:
- 1≤n≤5×105,0≤k<220;
- 对于所有 1≤i≤n,均有 0≤ai<220。
| 测试点编号 | n≤ | k | 特殊性质 |
|---|---|---|---|
| 1 | 2 | =0 | A |
| 2 | 10 | ≤1 | B |
| 3 | 102 | =0 | A |
| 4,5 | 102 | ≤1 | B |
| 6∼8 | 102 | ≤255 | C |
| 9,10 | 103 | ≤255 | C |
| 11,12 | 103 | <220 | 无 |
| 13 | 2×105 | ≤1 | B |
| 14,15 | 2×105 | ≤255 | C |
| 16 | 2×105 | <220 | 无 |
| 17 | 5×105 | ≤255 | C |
| 18∼20 | 5×105 | <220 | 无 |
特殊性质 A:对于所有 1≤i≤n,均有 ai=1。
特殊性质 B:对于所有 1≤i≤n,均有 0≤ai≤1。
特殊性质 C:对于所有 1≤i≤n,均有 0≤ai≤255。
部分分
- 5 分
测试点 1:n≤2,k=0,特殊性质 A。
- 5 分
测试点 2:n≤10,k≤1,特殊性质 B。
- 5 分
测试点 3:n≤102,k=0,特殊性质 A。
- 10 分
测试点 4,5:n≤102,k≤1,特殊性质 B。
- 15 分
测试点 6∼8:n≤102,k≤255,特殊性质 C。
- 10 分
测试点 9,10:n≤103,k≤255,特殊性质 C。
- 10 分
测试点 11,12:n≤103,k<220,无特殊性质。
- 5 分
测试点 13:n≤2×105,k≤1,特殊性质 B。
- 10 分
测试点 14,15:n≤2×105,k≤255,特殊性质 C。
- 5 分
测试点 16:n≤2×105,k<220,无特殊性质。
- 5 分
测试点 17:n≤5×105,k≤255,特殊性质 C。
- 15 分
测试点 18∼20:n≤5×105,k<220,无特殊性质。
你的代码(C++)
提交后由评测机编译运行,结果见下方76 B / 64 KB