题意:刚开始有一个空集合,现在有三种操作1,加x到集合中,2,删去集合中的一个x,3,查询集合中的x^p<l的个数
套路题,(看到异或和集合操作条件反射01字典树),加和删操作不说了,主要是查询,当l二进制中的第x位是1,那么取p第x位的异或时该位就是1,那么加上另一边(即p的第x位)的个数,当l第x位是0时,此时只能找p的第x位来和它异或得到0,从上向下扫一遍就是答案了,复杂度O(nlogn)
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pil pair<int,ll> #define pii pair<int,int> #define ull unsigned long long #define base 1000000000000000000 #define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-9; const int N=100000+10,maxn=3000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; struct Trie{ int tot,root; int Next[N*32][3],cnt[N*32]; int newnode() { memset(Next[tot],-1,sizeof Next[tot]); cnt[tot]=0; return tot++; } void init() { tot=0; root=newnode(); } void ins(int x) { int now=root; for(int i=30;i>=0;i--) { if(Next[now][(x>>i)&1]==-1) Next[now][(x>>i)&1]=newnode(); now=Next[now][(x>>i)&1]; // printf("%d+++ ",now); cnt[now]++; } } void del(int x) { int now=root; for(int i=30;i>=0;i--) { cnt[Next[now][(x>>i)&1]]--; if(cnt[Next[now][(x>>i)&1]]==0) { Next[now][(x>>i)&1]=-1; break; } now=Next[now][(x>>i)&1]; // printf("%d---%d ",now,cnt[now]); } } int query(int x,int y) { int now=root,ans=0; for(int i=30;i>=0;i--) { int px=(x>>i)&1,py=(y>>i)&1; if(py) { if(Next[now][px]!=-1) { ans+=cnt[Next[now][px]]; // if(cnt[Next[now][px^1]])printf("%d!!!! ",Next[now][px^1]); } now=Next[now][px^1]; } else { now=Next[now][px]; } if(now==-1)break; } return ans; } }s; int main() { int q; scanf("%d",&q); s.init(); while(q--) { int op; scanf("%d",&op); if(op==1) { int x; scanf("%d",&x); s.ins(x); } else if(op==2) { int x; scanf("%d",&x); s.del(x); } else { int x,y; scanf("%d%d",&x,&y); printf("%d ",s.query(x,y)); } } return 0; } /******************** ********************/