NC14247 Xorto

题目

题目描述

给定一个长度为 n 的整数数组,问有多少对互不重叠的非空区间,使得两个区间内的数的异或和为 0

输入描述

第一行一个数 n 表示数组长度;
第二行 n 个整数表示数组;
1n1000, 0<100000

输出描述

一行一个整数表示答案。

示例1

输入

3
0 0 0

输出

5

说明

([1,1],[2,2]),([1,1],[3,3]),([1,1],[2,3]),([1,2],[3,3]),([2,2],[3,3])

题解

知识点:前缀和,枚举。

注意到区间是不重合但长度不定,考虑枚举左区间的右端点 i 。对于某个左区间右端点 i ,枚举左区间左端点 j ,左区间可能被右区间重复匹配,考虑利用数组 cnt 记录某个异或值的左区间个数;对于某个左区间右端点 i ,固定右区间左端点为 i+1, 枚举右区间的右端点 j ,与之前记录的 cnt 进行匹配。

时间复杂度 O(n2)

空间复杂度 O(1)

代码

#include <bits/stdc++.h>
using namespace std;
int a[1007],cnt[2*100000+7];
int main(){
std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i = 1;i<=n;i++){
cin>>a[i];
a[i] ^= a[i-1];
}
long long ans = 0;///O(n^4)空间 大概1x10^12>2*10^9
for(int i = 1;i<=n;i++){///向左遍历左区间的右端点i。对于一组相同端点的左区间,一定会被其右端点往后的点作为左端点的右区间遍历匹配,因此每次处理都保留
for(int j = 1;j<=i;j++){///遍历以i为右端点的左区间的左端点
cnt[a[i]^a[j-1]]++;
}
for(int j = i+1;j<=n;j++){///遍历以i+1为左端点的右区间的右端点
ans+=cnt[a[j]^a[i]];
}
}
cout<<ans<<'\n';
return 0;
}
posted @   空白菌  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示