题意:
解法:
容易想到01字典树,
操作1和操作2是字典树的基本操作,
对于操作3,如果在树上走x^p=l的前缀,
对于某一位,如果走另一条路径会使得x^p<l,那么加上另一条路径的size即可.
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=1e5+5;
struct Trie{
int a[maxm*32][2],tot=1;
int sz[maxm*32];
void add(int x){
int node=1;
for(int i=30;i>=0;i--){
int v=(x>>i&1);
if(!a[node][v])a[node][v]=++tot;
node=a[node][v];
sz[node]++;
}
}
void del(int x){
int node=1;
for(int i=30;i>=0;i--){
int v=(x>>i&1);
if(!a[node][v])a[node][v]=++tot;
node=a[node][v];
sz[node]--;
}
}
int ask(int x,int y){
int node=1;
int ans=0;
for(int i=30;i>=0;i--){
int v1=(x>>i&1),v2=(y>>i&1);
int v=(v1^v2);//走v的话,是等于v2
if((v1^(v^1))<v2){//如果走v^1会更小,则加上贡献
ans+=sz[a[node][v^1]];
}
node=a[node][v];
if(!node)return ans;
}
return ans;
}
}T;
void solve(){
int q;cin>>q;
while(q--){
int op;cin>>op;
if(op==1){
int x;cin>>x;T.add(x);
}else if(op==2){
int x;cin>>x;T.del(x);
}else if(op==3){
int x,y;cin>>x>>y;
int ans=T.ask(x,y);
cout<<ans<<endl;
}
}
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}