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 Trie树/multiset

题目:http://codeforces.com/problemset/problem/706/D 题意: +表示吧这个数加到集合中,-表示把这个数从集合中减去一次,?表示集合里面的一个y使的x...
  • hjt_fathomless
  • hjt_fathomless
  • 2016年09月01日 09:20
  • 177

CodeForces 367D Vasiliy's Multiset Trie树

D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes input ...
  • HandsomeHow
  • HandsomeHow
  • 2016年08月12日 22:36
  • 336

【codeforces 681C】【优先队列+模拟】 Heap Operations

传送门:http://codeforces.com/contest/681/problem/C 思路: 因为本题的操作是一系列关于堆的操作,而且数据规模也合适,所以我们可以直接用一个堆来模拟这些操作...
  • guhaiteng
  • guhaiteng
  • 2016年11月13日 00:16
  • 236

C++ STL set和multiset的使用 hunst_xiehonghao 总结

C++ STL set和multiset的使用 std::set s;那个s这个对象里面存贮的元素是从小到大排序的,(因为用std::less作为比较工具。) 1,set的含义是集合,它是一个...
  • hnust_xiehonghao
  • hnust_xiehonghao
  • 2012年09月04日 15:54
  • 13928

Codeforces 876B Divisiblity of Differences

B. Divisiblity of Differences time limit per test 1 second memory limit per test 512 megabytes ...
  • Leo_Nasir
  • Leo_Nasir
  • 2017年10月17日 21:07
  • 467

CodeForces 706D Vasiliy's Multiset

传送门:706D D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabyte...
  • telecomadmin
  • telecomadmin
  • 2016年08月12日 22:21
  • 197

STL之容器set和multiset的用法详解

原文链接:http://blog.csdn.net/xiajun07061225/article/details/7459206 一、set和multiset基础 set和multiset会...
  • sinat_20265495
  • sinat_20265495
  • 2016年12月05日 10:37
  • 387

UVA 11020 multiset、lower_bound、 upper_bound STL里面的排序二叉树

题目大意:有n个人,每个
  • u013573047
  • u013573047
  • 2014年08月11日 11:14
  • 790

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

D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes ...
  • liangzhaoyang1
  • liangzhaoyang1
  • 2016年08月13日 12:59
  • 633

oracle 特殊SQL(TABLE( CAST( MULTISET()

求条sql语句成绩表--xh 学号  cj 成绩create table b_cj(xh varchar2(50),cj number);insert into b_cj values('1',67)...
  • wanglipo
  • wanglipo
  • 2011年04月15日 16:58
  • 4805
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Codeforces 706D-Vasiliy's Multiset(Trie树)
举报原因:
原因补充:

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