跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 算法题:统计满足异或和等于和的子数组数量

一道 C++ 算法题,要求统计数组中异或和等于算术和的子数组数量。基于异或是无进位加法的性质,若区间内任意位不重叠则满足条件。文章提供了两种解法:一是使用前缀和配合双指针,二是直接使用滑动窗口维护当前区间的异或状态。两种方法时间复杂度均为 O(n),重点在于利用右指针的单调性避免重复计算,并修正了代码中的常见语法错误。

芝士奶盖发布于 2026/3/26更新于 2026/8/1748 浏览

题目描述

给定一个长度为 n 的数组 a,请问有多少个子数组是'神奇数组'。 换句话说,在数组 a 中存在多少对下标 l 和 r (1≤l≤r≤n) 满足: a_l ⊕ a_{l+1} ⊕ ... ⊕ a_r = a_l + a_{l+1} + ... + a_r 其中 ⊕ 表示按位异或运算。

输入格式

第一行输入一个整数 n,表示数组 a 的长度。 第二行输入 n 个整数,表示数组 a 的值。 数据保证 1 ≤ n ≤ 2×10^5,0 ≤ a_i < 2^20。

输出格式

输出一个整数表示答案。

解题思路

异或运算可以视为不进位加法。如果两个二进制数相加时没有产生进位,那么它们的异或值等于相加的值。该性质推广到多个数也成立。因此,对于一个'神奇数组'来说,每一个比特位最多只有一个数在该位为 1。如果某个比特位不止一个数在该位为 1,那么在相加时就会产生进位,导致异或和不等于和。

根据这个性质,我们需要枚举每个数作为数组的左边界 l,看最多有多少个右边界 r 使得区间 [l, r] 满足性质。由于左端点固定时,一旦冲突出现(即某一位有两个 1),继续向右扩展只会增加冲突,不会消除,因此右边界具有单调性。我们可以使用双指针来维护区间。

方法一:前缀和 + 双指针

维护前缀和数组和前缀异或数组,通过查询区间和与区间异或值来判断合法性。复杂度 O(n)。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N=2e5+10;
ll a[N];
ll preSum[N], x[N];

int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n; cin>>n;
    preSum[0]=0; x[0]=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        preSum[i]=preSum[i-1]+a[i];
        x[i]=(x[i-1]^a[i]);
    }
    int i=1,j=1;
    ll cnt=0;
    (i<=n&&j<=n){
        ((x[i]^x[j])==(preSum[j]-preSum[i])){
            cnt+=j-i;
            j++;
        }
         i++;
    }
    cout<<cnt<<;
     ;
}
while
if
-1
-1
+1
else
'\n'
return
0

方法二:滑动窗口(双指针)

直接维护当前窗口的异或和,利用性质判断扩展右边界。当左边界移动时,移除元素不会引入新冲突,右边界只需向右尝试。复杂度 O(n)。

#include<bits/stdc++.h>
using namespace std;
using ll=long long;

int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n; cin>>n;
    vector<int>a(n);
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    int l=0,r=0,res=0;
    ll ans=0;
    while(l<n){
        while(r<n&&((res^a[r])==(res+a[r]))){
            res^=a[r];
            r++;
        }
        ans+=r-l;
        res^=a[l];
        l++;
    }
    cout<<ans<<'\n';
    return 0;
}

总结

本题核心在于理解异或运算与加法运算在无进位情况下的等价性。利用这一性质,结合双指针技巧,可以在 O(n) 时间内高效统计满足条件的子数组数量。注意代码实现时的语法细节及输入输出优化。

目录

  1. 题目描述
  2. 输入格式
  3. 输出格式
  4. 解题思路
  5. 方法一:前缀和 + 双指针
  6. 方法二:滑动窗口(双指针)
  7. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenCode 开源 AI 编程助手使用指南
  • RAG 入门教程:LangChain 框架中的向量存储
  • Java 队列:原理、实现与高频实战
  • Gdspy Python 芯片设计库安装与使用指南
  • 夸克网盘精选资源:电子书、软件与 AI 学习资料汇总
  • CTFShow Web 入门命令执行 29-124 通关详解
  • Java 虚拟机内存模型详解
  • Sora 刷屏时代,产品经理会被 AI 取代吗?
  • 算法实战:位运算解决两数之和、唯一数字及消失数字问题
  • C++ 类与对象:深入解析默认成员函数
  • AI 赋能原则 10 解读:政府 2.0 与全民能力跃迁
  • 基于 Docker 在 Windows 部署闲鱼 AI 自动回复系统
  • 手写 C++ Shell 解释器,解密 Bash 背后的进程创建机制
  • 3661 可以被机器人摧毁的最大墙壁数目 - 离散化与线段树解法
  • FPGA 面试题汇总整理
  • Coze(扣子)全解析:100个落地用途+发布使用指南,小白也能玩转低代码AI智能体
  • RabbitMQ 工作模式实战:Work Queue 负载均衡与 fanout 发布订阅
  • DeepSeek 与通义万相结合高效制作 AI 视频实战详解
  • B205mini FPGA 工程架构与开发流程解析
  • Google 发布多模态嵌入模型 Gemini Embedding 2,MuleRun 推出自进化个人 AI

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online