• Codeforces #367 (Div. 2) D. Vasiliy's Multiset (trie 树)


    http://codeforces.com/group/1EzrFFyOc0/contest/706/problem/D 

    题目:就是有3种操作

    + x向集合里添加 x

    - x 删除x元素,(保证存在

    ? x 查询 x |  集合中元素的最大值

    思路:就是利用字典树,从高位到低位进行贪心。 比如说给一个数 x=3  , 对x 各位取反(二进制)(x=~x ),

    于是就是 1-0-0-1; 拿 1-0-0-1,从左到右(从高位到地位)顺序,来在字典树中寻找。如果能找到(if ),就接着找下去;

    如果找不到(else),就退而求其次(贪心),找另外一个分岔点

    在构造的时候从32或者31开始,大于1e9,相当于0-0-0-0-0-0-0-0-0-0-0-0-1-0-1-1 这样 ,在树中 前面多几个0没关系。

    不过数组要尽量开大一点(尽管我不知道具体应该开多少)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include <cctype>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cmath>
     7 #include<string>
     8 #include<cmath>
     9 #include<set>
    10 #include<vector>
    11 #include<stack>
    12 #include<queue>
    13 #include<map>
    14 using namespace std;
    15 #define ll long long
    16 #define mem(a,x) memset(a,x,sizeof(a))
    17 #define se second
    18 #define fi first
    19 const int INF= 0x3f3f3f3f;
    20 const int N=4e6+5;
    21 
    22 int n,cnt=1;
    23 int trie[N][2]={0},num[N]={0}; 
    24 
    25 void insert(int c,ll x)
    26 {
    27     int rt=0;
    28     for(int i=31;i>=0;i--)
    29     {
    30         int k=(x>>i)&1; //二进制高位到低位的 0 1情况
    31         if(!trie[rt][k]) 
    32             trie[rt][k]=cnt, cnt++;
    33         rt=trie[rt][k];
    34         
    35         num[rt]+=c; 
    36     }
    37 }
    38 
    39 ll find(ll x)
    40 {
    41     x=~x;
    42     int rt=0;
    43     ll ans=0;
    44     for(int i=31;i>=0;i--)
    45     {
    46         int k=(x>>i)&1;
    47         ans=ans<<1;
    48         if( num[trie[rt][k] ] && trie[rt][k] )
    49         {
    50             ans++;
    51             rt=trie[rt][k];
    52         }
    53         else
    54             rt=trie[rt][1-k];  //贪心 
    55     }
    56     return ans;
    57 } 
    58 int main()
    59 {
    60     cin>>n;
    61     char c;
    62     ll x;
    63     
    64     insert(1,0);
    65     for(int i=1;i<=n;i++)
    66     {
    67         cin>>c>>x;
    68         if(c=='+')
    69             insert(1,x);
    70         else if(c=='-')
    71             insert(-1,x);
    72         else
    73             printf("%lld
    ",find(x));
    74         //cout<<c<<x<<endl;
    75     }
    76 }
  • 相关阅读:
    程序数据校验
    修改文件名后,pip命令报错:Fatal error in launcher: Unable to create process using
    算法竞赛平台
    连续子数组的元素之和最大值
    【数学计算】圆周率
    使用DOS命令关闭tomcat端口(其他服务也是可以的)
    微软project文件mpp解析
    关于读取上传文件问题的两个解决办法
    关于office在卸载了某一应用之后无法试图使用的功能所在的网络位置
    关于eclipse的一些问题
  • 原文地址:https://www.cnblogs.com/thunder-110/p/9450467.html
Copyright © 2020-2023  润新知