题解:CF706D Vasiliy's Multiset(提供一种不用字典树的做法)
做法
首先,多重集的插入删除直接使用 multiset 实现即可。
再考虑到这种异或最大值的几乎是通用的解法就是拆位然后二进制从高往低贪心地考虑。
如何具体去去做呢?假设当前集合内有
就可以这样做:\
从高位往低位考虑,对于这种情况,我们就要先考虑是否存在 lower_bound。
对于每一步都这样贪下去,就可以达到我们的答案了。
最终时间复杂度就是
CODE
#include<bits/stdc++.h>
using namespace std;
multiset<int>st;
const int M=30;
bool check(int l,int r){
auto it=st.lower_bound(l);
return it!=st.end()&&*it<=r;
}
int main(){
st.insert(0);
int q;cin>>q;
while(q--){
char c;int x;cin>>c>>x;
if(c=='+')st.insert(x);
if(c=='-')st.erase(st.find(x));
if(c=='?'){
int tmp=0;
for(int i=M-1;i>=0;--i){
if((x>>i)&1){
if(!check(tmp,tmp+(1<<i)-1))
tmp+=(1<<i);
}
else{
if(check(tmp+(1<<i),tmp+(1<<(i+1))-1))
tmp+=(1<<i);
}
}
cout<<(tmp^x)<<'\n';
}
}
}