子段异或(异或前缀和)
第一行一个整数 n ,代表数列长度。
第二行 n 个整数,代表数列。
输出描述:
输出一个整数,代表答案。
示例1
意思就是给你一个子串,问有多少个子串异或和为0
解析:就是先知道一个知识就是如果x^y==0,则x==y。
设b[i]为异或前缀和,则
b[i] = a[1] ^ a[2] ^ ... ^ a[i - 1] ^ a[i]
那么对于一段[1,r]来说,异或前缀和为b[r],那么如果想要以r结尾的异或为0的子段的右半部分,
那么只需要前面出现过一个数b[i] == b[r],那么[i + 1,r]这一段异或和为0
就是:如果在r的前面出现一个i,使得b[i]==b[r]则i+1到r的异或和为0
#include<map> #include<string> #include <math.h> #include<memory.h> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; int read() { int x = 0, f = 1; char s; while((s = getchar()) > '9' || s < '0') {if(s == '-') f = -1;} while(s <= '9' && s >= '0') { x = (x << 1) + (x << 3) + (s ^ 48); s = getchar(); } return x * f; } const int INF=0x3f3f3f3f; const int maxn=1e6+122; //子段异或和为0 //设b[r]为他的异或前缀和 //有b[r]==b[1]^b[2]......^b[r] //如果在前面出现一个b[i]==b[r]则i+1到r的异或和为0 map<int,int>mp; ll a[maxn]; ll b[maxn]; int main(){ int n; cin>>n; ll ans=0; for(int i=1;i<=n;i++){ cin>>a[i]; b[i]=b[i-1]^a[i]; if(b[i]==0){ ans++; } ans+=mp[b[i]]; mp[b[i]]++; } cout<<ans<<endl; }
例二:
传送门

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!