专栏文章
题解:P8955 「VUSC」Card Tricks
P8955题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mini3pld
- 此快照首次捕获于
- 2025/12/02 02:47 3 个月前
- 此快照最后确认于
- 2025/12/02 02:47 3 个月前
这是一道可癌的毒瘤数据结构题。
前置知识
思路
我们考虑在线段树上二分,线段树维护 到 的修改的异或和,我们遍历每个点,在线段树上二分异或的次数。
那么我们如何才能知道那些修改对那些点有效呢,我们可以创建 个
vector,每个操作其实就是在第 个 vector 中加入,在第 个 vector 中删除。时间复杂度 。
Code
CPP#include<iostream>
#include<vector>
using namespace std;
const int N = 1e6 + 10;
int n,q,P,dat[N];
vector<pair<int,int> > pos[N];
namespace SegmentTree{
int sum[N << 2];
void update(int p,int pos,int val,int l,int r){
if(l == r){
sum[p] = val;
return;
}
int mid = (l + r) >> 1;
if(pos <= mid){
update(p << 1,pos,val,l,mid);
}else{
update(p << 1 | 1,pos,val,mid + 1,r);
}
sum[p] = (sum[p << 1] | sum[p << 1 | 1]);
}
int query(int p,int l,int r,int k){
if((sum[p] | k) <= P){
return -1;
}
if(l == r){
return l;
}
int mid = (l + r) >> 1;
if((sum[p << 1] | k) > P){
return query(p << 1,l,mid,k);
}else{
return query(p << 1 | 1,mid + 1,r,(k | sum[p << 1]));
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> q >> P;
for(int i = 1;i <= n;i ++){
cin >> dat[i];
}
for(int i = 1;i <= q;i ++){
int l,r,k;
cin >> l >> r >> k;
pos[l].push_back({i,k});
pos[r + 1].push_back({i,0});
}
for(int i = 1;i <= n;i ++){
for(pair<int,int> p : pos[i]){
int id = p.first,val = p.second;
SegmentTree::update(1,id,val,1,q);
}
cout << SegmentTree::query(1,1,q,dat[i]) << " ";
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...