Vasiliy's Multiset CodeForces -706D || 01字典树模板

就是一个模板

注意这题有一个要求:有一个额外的0一直保持在集合中

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int _LEN=30;
 5 //上限为2^30-1,即二进制最多30位
 6 int lft[40];
 7 namespace Trie
 8 {
 9     int ch[7001000][2],sz[7001000];
10     int mem;
11     void insert(int x,int cur)
12     {
13         int i;bool t;
14         for(i=_LEN-1;i>=0;--i)
15         {
16             t=x&lft[i];
17             if(!ch[cur][t])    ch[cur][t]=++mem;
18             ++sz[cur];cur=ch[cur][t];
19         }
20         ++sz[cur];
21     }
22     int query(int x,int cur)
23     {
24         int i,ans=0;bool t;
25         for(i=_LEN-1;i>=0;--i)
26         {
27             t=x&lft[i];
28             if(sz[ch[cur][t^1]])    ans|=lft[i],cur=ch[cur][t^1];
29             else    cur=ch[cur][t];
30         }
31         return ans;
32     }
33     void erase(int x,int cur)
34     {
35         int i;bool t;
36         for(i=_LEN-1;i>=0;--i)
37         {
38             t=x&lft[i];
39             --sz[cur];cur=ch[cur][t];
40         }
41         --sz[cur];
42     }
43 };
44 int root;
45 char ss[10];
46 int main()
47 {
48     int i,q,x;
49     lft[0]=1;
50     for(i=1;i<=_LEN;i++)    lft[i]=lft[i-1]<<1;
51     root=++Trie::mem;Trie::insert(0,root);
52     scanf("%d",&q);
53     while(q--)
54     {
55         scanf("%s%d",ss,&x);
56         if(ss[0]==‘+‘)
57         {
58             Trie::insert(x,root);
59         }
60         else if(ss[0]==‘-‘)
61         {
62             Trie::erase(x,root);
63         }
64         else if(ss[0]==‘?‘)
65         {
66             printf("%d\n",Trie::query(x,root));
67         }
68     }
69     return 0;
70 }

Vasiliy's Multiset CodeForces -706D || 01字典树模板

原文地址:https://www.cnblogs.com/hehe54321/p/8718645.html

时间: 2024-12-25 05:08:13

Vasiliy's Multiset CodeForces -706D || 01字典树模板的相关文章

Codeforces 706D Vasiliy&#39;s Multiset(可持久化字典树)

[题目链接] http://codeforces.com/problemset/problem/706/D [题目大意] 要求实现一个集合中的三个操作,1:在集合中加入一个元素x,2:从集合中删除一个元素x(保证x存在),3:要求从集合中选出一个数,使得其与给出的数x的异或值最大,输出这个异或值. [题解] 可以将所有的以二进制形式存在01字典树上,删除即插入权值为-1的二进制串,对于异或值最大的操作,我们只要在字典树上按位贪心,从最高位开始尽量保证该位存在最后就能得到答案.写代码的时候直接写了

[01字典树]求序列完美度(求区间最大异或值)

https://nanti.jisuanke.com/t/15531 解题关键:01字典树模板,用字典树保存每个数的二进制表示,从而动态维护区间上的最大异或值,注意添加和删除都可以用于一个change函数表示. 复杂度:$O(n\log n + {n^2}\log n)$ 1 #include<bits/stdc++.h> 2 #define maxn 1005 3 #define inf 0x3f3f3f3f 4 using namespace std; 5 typedef long lon

HDU6191(01字典树启发式合并)

Query on A Tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 801    Accepted Submission(s): 302 Problem Description Monkey A lives on a tree, he always plays on this tree. One day, monkey

2014百度之星资格赛—— Xor Sum(01字典树)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起

01字典树贪心查询+建立+删除(个人模版)

01字典树贪心查询+建立+删除: 1 #define maxn 2 2 typedef struct tree 3 { 4 tree *nex[maxn]; 5 int v; 6 int val; 7 }tree; 8 tree root; 9 void init() 10 { 11 for(int i=0;i<maxn;i++) 12 { 13 root.nex[i]=NULL; 14 } 15 } 16 void creat(char *str,int va) 17 { 18 int len

Chip Factory---hdu5536(异或值最大,01字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536 题意:有一个数组a[], 包含n个数,从n个数中找到三个数使得 (a[i]+a[j])⊕a[k]最大,i,j,k不同; 求异或的结果最大所以我们可以用01字典树,先把所有的数加入字典树中,从n个数中选出两个数a[i]和a[j], 先把他们从字典树中删除,然后找到与a[i]+a[j]异或最大的数,和结果取最大值即可: 最后不要忘记再把a[i]和a[j]添加到字典树中即可: #include<st

HDU 4825 Xor Sum 【01字典树】

题面: Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大.Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助.你能证明人类的智慧么? Input 输入包含若干组测试数据,每组

HDU4825/5536 [01 字典树/简单字典树更新]

Xor Sum Time Limit: 1000 MS Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大.Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助.你能证明人类的智慧么? Input 输入包含若干组测试数

异或最大值(01字典树)

/** 异或最大值(01字典树) 题意:求n个非负数中任意2个的异或值的最大值.n数量级为10^5 分析:直接暴力肯定超时了.一个非负整数可以看成1个32位的01字符串,n个数可以看成n个字符串,因此可以建立字典树, 建好树后,对于任意非负整数x,可以沿着树根往下贪心找到y,使得x异或y最大,复杂度为树的深度. */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iost