Vasiliy's Multiset

来源:互联网 发布:系统表的定义sql语句 编辑:程序博客网 时间:2024/06/05 06:09
链接:http://acm.hust.edu.cn/vjudge/problem/460314/origin

题目:

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:

  1. "+ x" — add integer x to multiset A.
  2. "- x" — erase one occurrence of integerx from multiset A. It's guaranteed that at least onex is present in the multiset A before this query.
  3. "? 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 integery 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 100020struct 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;}

0 0
原创粉丝点击