【CF706D】Vasiliy‘s Multiset (Trie字典树求异或+添加 删除 查询操作)

Vasiliy’s Multiset

题目大意:

有三种类型的查询:
“+ x” - 添加一个整数 X。
“ - x” - 删除一次整数 X。它保证至少有一个 X 存在于查询前的集合中。
“?x” - 给定整数 X 并且需要计算该值和一个整数Y的按位异或(也称为XOR)的最大值
这是一个允许相等元素的集合。

解题思路:

如果没有删除的话就是字典树求异或和模板题了,而现在需要有删除操作,我们新开一个index数组记录一下已有的节点即可(不能开bool数组,因为集合中可能有重复元素),添加就+1,删除-1,查询的时候>=1才可以到达此节点。

一定要记得提前把 0插入倒树里并标记为1,insert(0,1),一开始忘了这个操作,然后wa了5次

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int MAXN = 200007;
int t[MAXN<<5][3],tot=1,index[MAXN<<5];

void insert(int x,int w){                         //插入到字典树
    int p=1;
    for(int k=31;k>=0;k--){               //转换成01串
        int ch=x>>k&1;                      // if(x&(1<<i)) ch=1; else ch=0;
        if(!t[p][ch]){
        	t[p][ch]=++tot;
		} 
        p=t[p][ch];
        index[p]+=w;
    }
}

int search(int x){
    int p=1,ans=0;
    for(int k=31;k>=0;k--){
        int ch=x>>k&1;
        if(index[t[p][ch^1]]){                     //尽可能找不一样的,贪心思想
            p=t[p][ch^1];
            ans|=1<<k;
        }else p=t[p][ch];
    }
    return ans;
}


int main(){
    int n,m,T,w;
    char op[2];
    memset(t,0,sizeof t);
    memset(index,0,sizeof index);
    scanf("%d",&T);
    insert(0,1);       //提前把0标记为1
    for(int k=1;k<=T;k++){
    	scanf("%s%d",op,&n);
    	if(op[0]=='+') insert(n,1);
        else if(op[0]=='-') insert(n,-1);
        else printf("%d\n", search(n));
	}
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值