Codeforces 706D Vasiliy's Multiset(可持久化字典树)

Posted forever97‘s blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 706D Vasiliy's Multiset(可持久化字典树)相关的知识,希望对你有一定的参考价值。

 

【题目链接】  http://codeforces.com/problemset/problem/706/D

 

【题目大意】

    要求实现一个集合中的三个操作,1:在集合中加入一个元素x,2:从集合中删除一个元素x(保证x存在),3:要求从集合中选出一个数,使得其与给出的数x的异或值最大,输出这个异或值。

 

【题解】

  可以将所有的以二进制形式存在01字典树上,删除即插入权值为-1的二进制串,对于异或值最大的操作,我们只要在字典树上按位贪心,从最高位开始尽量保证该位存在最后就能得到答案。写代码的时候直接写了个持久化的字典树,普通字典树也可以实现这样子的功能。

 

【代码】

#include <cstdio>
#include <algorithm> 
const int N=600005,inf=2000000000;
using namespace std;
int bin[32],n,m,a[N],b[N],root[N];
struct trie{
    int cnt,ch[N*32][2],sum[N*32];
    int insert(int x,int val,int d){
        int tmp,y;tmp=y=++cnt;
        for(int i=30;i>=0;i--){
        int t=val&bin[i];t>>=i;
            ch[y][0]=ch[x][0];ch[y][1]=ch[x][1];
        x=ch[x][t]; y=ch[y][t]=++cnt;
        sum[y]=sum[x]+d; 
        }return tmp;
    }
    int query(int l,int r,int val){
        int tmp=0;
        for(int i=30;i>=0;i--){
        int t=val&bin[i];t>>=i;
        if(sum[ch[r][t^1]]-sum[ch[l][t^1]])tmp+=bin[i],r=ch[r][t^1],l=ch[l][t^1];
        else r=ch[r][t],l=ch[l][t];
        }return tmp;
    }
}T;
int Q,x;char t;
int main(){ 
    bin[0]=1;for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1;
    scanf("%d",&Q);
    root[1]=T.insert(root[0],0,1);
    for(int i=2;i<=Q+1;i++){
        scanf(" %c %d",&t,&x);
    if(t==‘+‘)root[i]=T.insert(root[i-1],x,1);
    else if(t==‘-‘)root[i]=T.insert(root[i-1],x,-1);
    else printf("%d\n",T.query(root[0],root[i]=root[i-1],x));
    }return 0;
}

  

以上是关于Codeforces 706D Vasiliy's Multiset(可持久化字典树)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 706D Vasiliy's Multiset(可持久化字典树)

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

trie树 Codeforces Round #367 D Vasiliy's Multiset

D. Vasiliy‘s Multiset(01Trie)

cf706D

Codeforces 702 D Road to Post Office