专栏文章

题解:P14359 [CSP-J 2025] 异或和 / xor(民间数据)

P14359题解参与者 12已保存评论 12

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
12 条
当前快照
1 份
快照标识符
@minfqlt3
此快照首次捕获于
2025/12/02 01:40
3 个月前
此快照最后确认于
2025/12/02 01:40
3 个月前
查看原文
题意: 给定一个长度为 nn 的序列 aakk,尝试选择尽可能多的不相交的区间,使每个区间的异或和都为 kk
思路: 由于 abb=aa\oplus b\oplus b=a,考虑使用类似前缀和的做法来求区间异或和,并用 map 存可以使区间 [1,i][1,i] 的异或和为 xx 的所有 ii。因为区间不相交,所以考虑维护最后一个区间的尾部,从 11nn 枚举 iiupper_bound 一下不小于最后一个区间的结尾,小于 ii,且 [j,i][j,i] 的异或和为 kk(即 [1,j][1,j] 的异或和 [1,i]\oplus [1,i] 的异或和)的最小的 jj(可以证明,选哪个 jj 不影响答案),如果找到了,答案加 11,更新最后一个区间的末尾。
代码:
CPP
#include<bits/stdc++.h>
using namespace std;
int a[500010],s[500010],vis=-1,ans,n,k;//vis初始化为-1,因为s[0]也可以用
map<int,vector<int>>mp;
int main(){
    cin>>n>>k;
    mp[0].push_back(0);
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=s[i-1]^a[i];
        mp[s[i]].push_back(i);
    }
    for(int i=1;i<=n;i++){
        auto pl=upper_bound(mp[s[i]^k].begin(),mp[s[i]^k].end(),vis);//求大于vis(即不小于最后一个区间的结尾)的最小j
        if(pl==mp[s[i]^k].end())continue;//防止访问空地址导致RE
        if(*pl<i)ans++,vis=i-1;
    }
    cout<<ans<<endl;
}

评论

12 条评论,欢迎与作者交流。

正在加载评论...