Description
神奇的cxlove有一颗平衡树,其树之神奇无法用语言来描述 OrzOrz。 这棵树支持3种操作: 1、加入一个数到树中,维护平衡树的合法性; 2、给一个数X,用O(1)的时间求出来树中的数Y使得 Y ^ X 最大(异或操作, Pascal 写作 xor , 0 ^ 0 = 0 , 1 ^ 1 = 0 , 0 ^ 1 = 1 , 1 ^ 0 = 1 , 2 ^ 3 = 1) 3、给一个数X,用O(1)的时间求出来树中的数Y使得 Y ^ X 最小(异或操作, Pascal
写作 xor , 0 ^ 0 = 0 , 1 ^ 1 = 0 , 0 ^ 1 = 1 , 1 ^ 0 = 1 , 2 ^ 3 = 1) 请你帮忙实现这颗树。 cxlove由于过于牛,有些事情是无法做到的,你能在1s以内通过就好了。 最后补充一句,cxlove是世界冠军!
Input
第一行是数据组数T (T ≤ 100)。
对于每组数据,第一行是操作数N (N ≤ 10000)。
以下 N 行,每行一个字符串一个数字,分别代表:
- insert X ,加入数 X
- qmax X ,求第2种操作的答案
- qmin X ,求第3种操作的答案
输入保证不存在空树Query的情况 (1 ≤ X ≤ 1e9)
Output
对于操作 2 , 3 输出相应的答案。
Sample Input
1 4 insert 1 insert 2 qmin 1 qmax 1
Sample Output
03
字典树
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> using namespace std; struct tire { tire* next[2]; tire(){memset(next,0,sizeof(next));} }*root; void insert(int x) { tire*j=root; for (int i=30;i>=0;i--) { int k=(x&(1<<i))?1:0; if (!j->next[k]) { j->next[k]=new tire; } j=j->next[k]; } } int get(int flag,int x) { int ans=x; tire*j=root; for (int i=30;i>=0;i--) { int k=(x&(1<<i))?1:0; if (j->next[flag^k]) { j=j->next[flag^k]; ans=ans^((flag^k)*(1<<i)); } else { j=j->next[1^flag^k]; ans=ans^((1^flag^k)*(1<<i)); } } return ans; } void dfs(tire* x) { for (int i=0;i<2;i++) if (x->next[i]) dfs(x->next[i]); delete x; } int main() { int n,T,x; char s[10]; scanf("%d",&T); while (T--) { if (root) dfs(root); root=new tire; scanf("%d",&n); while (n--) { scanf("%s%d",s,&x); if (s[0]=='i') insert(x); else printf("%d\n",get(s[2]=='i'?0:1,x)); } } }
温故而知新
#include<set> #include<map> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<bitset> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define rep(i,j,k) for (int i = j; i <= k; i++) #define per(i,j,k) for (int i = j; i >= k; i--) #define loop(i,j,k) for (int i = j;i != -1; i = k[i]) #define lson x << 1, l, mid #define rson x << 1 | 1, mid + 1, r #define fi first #define se second #define mp(i,j) make_pair(i,j) #define pii pair<int,int> using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const double eps = 1e-8; const int INF = 0x7FFFFFFF; const int mod = 10000; const int N = 29; const int read() { char ch = getchar(); while (ch<'0' || ch>'9') ch = getchar(); int x = ch - '0'; while ((ch = getchar()) >= '0'&&ch <= '9') x = x * 10 + ch - '0'; return x; } int T, n, x, sz; int f[N * 10000][2]; char s[N]; int clear(int x) { f[x][0] = f[x][1] = 0; return x; } int main() { T = read(); while (T--) { n = read(); clear(sz = 0); while (n--) { scanf("%s%d", s, &x); if (s[0] == 'i') { int rt = 0; per(i, N, 0) { int y = (x & (1 << i)) ? 1 : 0; if (!f[rt][y]) f[rt][y] = clear(++sz); rt = f[rt][y]; } } else { int rt = 0, ans = 0; if (s[2] == 'i') { per(i, N, 0) { int y = (x & (1 << i)) ? 1 : 0; if (f[rt][y]) rt = f[rt][y]; else rt = f[rt][y ^ 1], ans |= 1 << i; } } else { per(i, N, 0) { int y = (x & (1 << i)) ? 1 : 0; if (f[rt][y ^ 1]) rt = f[rt][y ^ 1], ans |= 1 << i; else rt = f[rt][y]; } } printf("%d\n", ans); } } } return 0; }