1 条题解
-
0
题意简化
数组 ,每次询问区间 ,求有多少子区间 满足:
- 从 开始的异或前缀序列单调不下降
即:设 ,要求 。
代码核心思路
1. 预处理关键信息
pre[i] = pre[i-1] ^ a[i]; // 前缀异或2. 单调性条件分析
代码中的
c(x, m)函数判断:从位置 开始,能否延伸到位置 (即区间 是否满足单调性)。关键定理: 等价于: 设 ,则 的第 位必须等于 的第 位。
证明:
- 单调条件 ⇒ 的第 位必须为
3. 前缀计数数组
f[0][i][h]和f[1][i][h]记录:- 前 个位置中, 的第 位为 的次数
- 前 个位置中, 的第 位为 的次数
用于快速判断条件。
4. 计算每个起点的最远延伸
对于每个起点 ,二分查找最大的 ,使得区间 满足单调性。
c(i, m)检查:- 对于所有位 ,检查是否有违反条件的情况
- 即: 的某位如果是 ,则 必须为 (没有中间位置的该位为 )
- 反之亦然
5. 主席树优化查询
对于询问 ,需要计算:
这等价于:对于每个 ,数轴区间 与 的交集长度求和。
主席树维护:
- 版本 :包含所有起点 的区间
- 查询: 与 的差,统计覆盖区间 的部分
算法步骤
-
输入预处理
- 计算前缀异或
- 计算每个数的最高位
-
构建计数数组
f[0/1][i][h]前缀和
-
计算
- 对每个 二分
- 用
c(i, m)检查单调性
-
构建主席树
- 对每个 ,将区间 插入主席树版本
-
回答询问
- 计算真正的 (强制在线)
- 查询主席树:区间 内有多少点被起点在 的区间覆盖
复杂度分析
- 预处理 数组:
- 计算 :二分 ,检查 ,总
- 主席树: 建树, 查询
- 总复杂度可过
关键优化
1. 单调性判定
将复杂的异或单调条件转化为位运算检查,用前缀计数数组 判断。
2. 二分延伸
对每个起点二分找最远延伸点,避免 。
3. 主席树统计
将区间求和问题转化为二维数点,用主席树高效查询。
样例解释
输入:
4 1 2 3 4计算 :
- :区间[1,2]满足
- :区间[2,2]满足
- :区间[3,4]满足
- :区间[4,4]满足
询问 :
- 起点1:贡献区间[1,2]与[1,3]交集长度2
- 起点2:贡献区间[2,2]与[1,3]交集长度1
- 起点3:贡献区间[3,4]与[1,3]交集长度1 总和:4
代码特点
- 位运算优化
- 二分+前缀检查
- 主席树维护区间覆盖
- 强制在线处理
- 1
信息
- ID
- 6021
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者