专栏文章
题解: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 的非负整数序列 和一个整数 。
定义区间 的权值为 。
要求选出最多的不相交区间,每个区间的权值都等于 。 输出最大区间数量。
定义区间 的权值为 。
要求选出最多的不相交区间,每个区间的权值都等于 。 输出最大区间数量。
2.贪心思路
这是一个经典的不相交区间选择问题,可以用贪心解决:
从左到右扫描,记录当前前缀异或和。
当我们发现当前前缀异或和 等于某个之前出现过的 时,说明区间 的权值是。 为了不相交,一旦我们选择了一个区间,就重置记录,从下一个位置重新开始(因为不能重叠)。
为什么这样贪心是对的?
因为如果我们在最早可能的位置结束一个区间,就能给右边留下更多的空间去形成新区间,这样总体数量不会比最优解差。
当我们发现当前前缀异或和 等于某个之前出现过的 时,说明区间 的权值是。 为了不相交,一旦我们选择了一个区间,就重置记录,从下一个位置重新开始(因为不能重叠)。
为什么这样贪心是对的?
因为如果我们在最早可能的位置结束一个区间,就能给右边留下更多的空间去形成新区间,这样总体数量不会比最优解差。
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 条评论,欢迎与作者交流。
正在加载评论...