【字典树】【贪心】Codeforces 706D Vasiliy's Multiset
题目链接:
http://codeforces.com/contest/706/problem/D
题目大意:
三种操作,1.添加一个数,2.删除一个数,3.查询现有数中与x异或最大值。(可重复)
题目思路:
【字典树】【贪心】
维护一个字典树,左0右1。查询时从上往下走。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // 2 //by coolxxx 3 // 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<memory.h> 9 #include<time.h> 10 #include<stdio.h> 11 #include<stdlib.h> 12 #include<string.h> 13 //#include<stdbool.h> 14 #include<math.h> 15 #define min(a,b) ((a)<(b)?(a):(b)) 16 #define max(a,b) ((a)>(b)?(a):(b)) 17 #define abs(a) ((a)>0?(a):(-(a))) 18 #define lowbit(a) (a&(-a)) 19 #define sqr(a) ((a)*(a)) 20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 21 #define mem(a,b) memset(a,b,sizeof(a)) 22 #define eps (1e-8) 23 #define J 10000000 24 #define MAX 0x7f7f7f7f 25 #define PI 3.1415926535897 26 #define N 5000004 27 using namespace std; 28 typedef long long LL; 29 int cas,cass; 30 int n,m,lll,ans; 31 int t[N]; 32 int ch[N][2]; 33 char c[1]; 34 void add(int x) 35 { 36 int i,j,k=1; 37 for(i=30;i>=0;i--) 38 { 39 j=((1<<i)&x)>0; 40 if(!ch[k][j])ch[k][j]=++lll; 41 k=ch[k][j]; 42 t[k]++; 43 } 44 } 45 void del(int x) 46 { 47 int i,j,k=1; 48 for(i=30;i>=0;i--) 49 { 50 j=((1<<i)&x)>0; 51 k=ch[k][j]; 52 t[k]--; 53 } 54 } 55 int find(int x) 56 { 57 int i,j,k=1; 58 ans=0; 59 for(i=30;i>=0;i--) 60 { 61 j=((1<<i)&x)==0; 62 if(t[ch[k][j]]) 63 { 64 ans|=(1<<i); 65 k=ch[k][j]; 66 } 67 else k=ch[k][1-j]; 68 } 69 return ans; 70 } 71 int main() 72 { 73 #ifndef ONLINE_JUDGE 74 // freopen("1.txt","r",stdin); 75 // freopen("2.txt","w",stdout); 76 #endif 77 int i,j,x; 78 // for(scanf("%d",&cas);cas;cas--) 79 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 80 // while(~scanf("%s",s)) 81 while(~scanf("%d",&n)) 82 { 83 mem(ch,0); 84 mem(t,0); 85 lll=1; 86 add(0); 87 for(i=1;i<=n;i++) 88 { 89 scanf("%s%d",c,&x); 90 if(c[0]=='+') 91 add(x); 92 else if(c[0]=='-') 93 del(x); 94 else printf("%d\n",find(x)); 95 } 96 } 97 return 0; 98 } 99 /* 100 // 101 102 // 103 */