Codeforces 706D-Vasiliy's Multiset(Trie树)

原创 2016年08月31日 09:57:02

题目链接请戳这里http://www.codeforces.com/problemset/problem/706/D
题目大意:
有一个允许多元素重复的集合A,集合初始的时候只有0。
输入一个整数q(1q200000),代表q个操作,每个操作有三种情况:
+ x:向集合中增加数x(1x109
- x:删除数x(确保x一定在集合中)
? x:求max xy,yA
题目分析:
一开始没有思路,通过百度发现涉及异或最大值的题都是将数据按从高到低位放在Trie树中,那么+和-操作就很好办了(Trie树就是按前缀保存的),?操作也好办,既然要求异或值最大,就从高到低往下搜索,使得与x相反的位尽可能多,一旦Trie树中存在与x对应位相反的前缀,就更新答案ans+=1<<i(其中i为位数)。
其实微软有一道机试题是跟子网段IP地址有关的,那道题是把IP地址的点分式拆成二进制形式,从高到低用Trie树维护,那么很显然Trie树的一个节点就是一个子网!,那道题中提到的admit和deny操作也就对应Trie树的添加前缀和删除前缀……

下面的ac代码可以用作Trie树的模板,将二叉树改为26叉树就可以适用于传统学习到的描述字母的Trie树。

#include <bits/stdc++.h>
using namespace std;

struct Trie {
  Trie* next[2];
  int cnt;
  Trie() {
    memset(next,0,sizeof(next));
    cnt=0;
  }
};
Trie* tr;
void insert(int n) {
  Trie *p=tr;
  for(int i=30;i>=0;i--) {
    int j=(n&(1<<i))?1:0;
    if(p->next[j]==NULL)
      p->next[j] = new Trie();
    p=p->next[j];
    p->cnt++;
  }
}
void del(int n) {
  Trie *p=tr;
  for(int i=30;i>=0;i--) {
    int j=(n&(1<<i))?1:0;
    p=p->next[j];
    p->cnt--;
  }
}
int query(int n) {
  int ans=0;
  Trie *p=tr;
  for(int i=30;i>=0;i--) {
    int j=(n&(1<<i))?0:1;
    if(p->next[j] && p->next[j]->cnt) {
      ans+=1<<i;
      p=p->next[j];
    }
    else {
      if(j==1)
        p=p->next[0];
      else
        p=p->next[1];
    }
  }
  return ans;
}

int main() {
  int q;
  tr = new Trie();
  insert(0);
  cin>>q;
  while(q--) {
    char c;
    int x;
    cin>>c>>x; //这个很慢!!!!
    if(c=='+')
      insert(x);
    else if(c=='-')
      del(x);
    else
      printf("%d\n", query(x));
  }
}
版权声明:完整版Leetcode题解请出门左转https://github.com/cmershen1/leetcode/tree/master/docs

相关文章推荐

【字典树】【贪心】Codeforces 706D Vasiliy's Multiset

题目链接:   http://codeforces.com/contest/706/problem/D 题目大意:   三种操作,1.添加一个数,2.删除一个数,3.查询现有数中与x异或最大值。(可重...

Codeforces 706D Vasiliy's Multiset【贪心+字典树】

D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes i...

codeforces 706D. Vasiliy's Multiset 带删除操作的字典树(真模版)

D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes i...
  • FTQOOO
  • FTQOOO
  • 2016年08月13日 16:07
  • 282

Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset 二进制树、Trie

二进制树、Trie 用一个二进制树(字典树的一种特殊化)来储存 child[x][k] 表示以x为父节点, k 为边, 的子节点 sz[x]表示这个节点的值, 值为0的时候节点不存在 查询的时候, 从...

Codeforces Round #367 (Div. 2) D——Vasiliy's Multiset(异或字典树)

D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes ...

CF 706D Vasiliy's Multiset

desription题目大致意思就是有一个整数集合A,A刚开始只有0,现在有m(m

Codeforces Round #367 (Div. 2) D Vasiliy's Multiset(查找树)

Author has gone out of the stories about Vasiliy, so here is just a formal task description. You ...

Codeforces Round #367 (Div. 2) D Vasiliy's Multiset(字典树+贪心)

题目链接 D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 me...
  • fouzhe
  • fouzhe
  • 2016年10月16日 17:00
  • 158

Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset(字典树模板)

这里戳题目题意:首先给你一个集合,这个集合里面一开始只有零(一开始是有零的,别用个空的集合,并且这个集合允许有重复的值),然后有三种操作,如果输入时加号,就往这个集合新增一个数字,如果是减号,就把减号...

Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset (tire 树)

D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Codeforces 706D-Vasiliy's Multiset(Trie树)
举报原因:
原因补充:

(最多只允许输入30个字)