专栏文章

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

P14359题解参与者 1已保存评论 0

文章操作

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

当前评论
0 条
当前快照
1 份
快照标识符
@minfpg1l
此快照首次捕获于
2025/12/02 01:39
3 个月前
此快照最后确认于
2025/12/02 01:39
3 个月前
查看原文

1. 题意理解

给定一个长度为 n 的非负整数序列a[1..n] a[1..n] 和一个整数 kk
定义区间 [l,r][l, r] 的权值为 a[l]a[l+1]...a[r]a[l] ⊕ a[l+1] ⊕ ... ⊕ a[r]
要求选出最多的不相交区间,每个区间的权值都等于 kk。 输出最大区间数量。

2.贪心思路

这是一个经典的不相交区间选择问题,可以用贪心解决: 从左到右扫描,记录当前前缀异或和。
当我们发现当前前缀异或和 p[r]p[r] 等于某个之前出现过的 p[pos]kp[pos] ⊕ k 时,说明区间[pos+1,r] [pos+1, r] 的权值是k k。 为了不相交,一旦我们选择了一个区间,就重置记录,从下一个位置重新开始(因为不能重叠)。
为什么这样贪心是对的?
因为如果我们在最早可能的位置结束一个区间,就能给右边留下更多的空间去形成新区间,这样总体数量不会比最优解差。

3.代码

CPP
#include <iostream>
#include <unordered_set>
using namespace std;
int main() {
    int n,k;
    cin>>n>>k;
    int a[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    
    if(k==0){
        int cnt=0;
        for(int i=0;i<n;i++){
            if(a[i]==0) cnt++;
        }
        cout<<cnt<<endl;
        return 0;
    }
    
    unordered_set<int>s;
    seen.insert(0);
    int p=0;
    int c=0;
    
    for(int i=0;i<n;i++){
        p^=a[i];
        if(s.find(p^k)!=s.end()){
            c++;
            s.clear();
            s.insert(p);
        } else {
            s.insert(p);
        }
    }
    
    cout<<c<<endl;
    
    return 0;
}

评论

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

正在加载评论...