链接:http://acm.hust.edu.cn/vjudge/problem/460314/origin
题目:
题意:有一个空的列表,里面可以存数字。共有3种操作:+:存一个(相同数字视为不同个体),-:删除一个(相同的数字只删掉一个),?:询问:给一个数,求列表里和这个数进行异或的最大值,输出这个结果
分析:,,,看了题解才知道看有一种方法可以算是二叉字典树(又或者叫二进制数字数????)来解决这个问题。就是把数字的二进制当作字符,利用字典树的查找特性来解决这个问题。然而知道了数据结构还是错的一塌糊涂。首先比对最大值,所以存的时候要从最高位开始,再之后。。。。。。。居然有什么都没存就开始查的情况。。。所以一定要预先存一个零进去。(记得维护一个n来记录这个数字存了几个)
题解:
题目:
Author has gone out of the stories about Vasiliy, so here is just a formal task description.
You are given q queries and a multiset A, initially containing only integer 0. There are three types of queries:
- "+ x" — add integer x to multiset A.
- "- x" — erase one occurrence of integer x from multiset A. It's guaranteed that at least one x is present in the multiset A before this query.
- "? x" — you are given integer x and need to compute the value , i.e. the maximum value of bitwise exclusive OR (also know as XOR) of integer x and some integer y from the multiset A.
Multiset is a set, where equal elements are allowed.
题意:有一个空的列表,里面可以存数字。共有3种操作:+:存一个(相同数字视为不同个体),-:删除一个(相同的数字只删掉一个),?:询问:给一个数,求列表里和这个数进行异或的最大值,输出这个结果
分析:,,,看了题解才知道看有一种方法可以算是二叉字典树(又或者叫二进制数字数????)来解决这个问题。就是把数字的二进制当作字符,利用字典树的查找特性来解决这个问题。然而知道了数据结构还是错的一塌糊涂。首先比对最大值,所以存的时候要从最高位开始,再之后。。。。。。。居然有什么都没存就开始查的情况。。。所以一定要预先存一个零进去。(记得维护一个n来记录这个数字存了几个)
题解:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <string>
#include <cstring>
#include <functional>
#include <cmath>
#include <cctype>
#include <cfloat>
#include <climits>
#include <complex>
#include <deque>
#include <list>
#include <set>
#include <utility>
#define rt return
#define fr freopen("in.txt","r",stdin)
#define fw freopen("out.txt","w",stdout)
#define ll long long
#define ull unsigned long long
#define detie ios_base::sync_with_stdio(false);cin.tie(false);cout.tie(false)
#define pii pair<int,int>
#define lowbit(x) x&(-x)
using namespace std;
#define maxi 0x3f3f3f3f
#define MAX 100020
struct Node
{
int count;
Node* next[2];
Node() :count(0) { memset(next, 0, sizeof next); }
}*root;
void insert(int num)
{
Node* p = root;
for (int i = 30; i >= 0; i--)
{
int k = (num&(1 << i)) ? 1 : 0;
if (!p->next[k])
p->next[k] = new Node;
p = p->next[k];
p->count++;
}
}
void del(int num)
{
Node* p = root;
for (int i = 30; i >= 0; i--)
{
int k = (num&(1 << i)) ? 1 : 0;
p = p->next[k];
if (p->count > 0)
p->count--;
}
}
int find(int num)
{
Node* p = root;
int sum = 0;
for (int i = 30; i >= 0; i--)
{
int k = 1 - ((num&(1 << i)) ? 1 : 0);
if (p->next[k] && p->next[k]->count > 0)
{
p = p->next[k];
sum += 1 << i;
}
else if (p->next[1 - k])
p = p->next[1 - k];
}
rt sum;
}
int main()
{
//fr;
detie;
root = new Node;
int t;
cin >> t;
insert(0);//吗各级啊。。。。。可能在什么都没有的时候查。。
while (t--)
{
char c;
int num;
cin >> c >> num;
switch (c)
{
case '+':insert(num); break;
case '-':del(num); break;
case '?':cout << find(num) << endl; break;
default:break;
}
}
rt 0;
}