【cf817E】Choosing The Commander

第一次写字典树题,记录一下

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
#define xf_dycm ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long int
#define ll long long
using namespace std;
//const ll mod=1e9+7;
const int MAXN=5e6+10;
ll pi,li;
ll q;
//01字典树
//把每个数字都转成2进制,按32位来存
ll trie[MAXN][2];//存字典树,存的是当前节点标号,下面连接的数字可能有1和2
ll tot=1;
ll num[MAXN];
void ist(ll n){
    ll P=0;//从树根开始
    for(int i=31;i>=0;i--){
        int ch=(n>>i)&1;//取二进制
        if(trie[P][ch]==0){
            trie[P][ch]=tot;
            tot++;
        }
        P=trie[P][ch];//P代表当前节点标号
        num[P]++;//标记这条分支上有几个士兵
    }
}
void dlt(ll n){
    ll P=0;
    for(int i=31;i>=0;i--){
        int ch=(n>>i)&1;
        P=trie[P][ch];
        if(!P)return;
        num[P]--;//这条分支上的士兵要少一个
    }
}
ll srh(ll p,ll l){
    ll ans=0;
    ll LL,PP;
    ll P=0;
    for(int i=31;i>=0;i--){
        PP=(p>>i)&1;LL=(l>>i)&1;
        if(LL==1&&PP==1){
            ans+=num[trie[P][1]];
            P=trie[P][0];
        } //l:1  p:1 +num[0] ->1
        else if(LL==1&&PP==0){
            ans+=num[trie[P][0]];
            P=trie[P][1];
        } //l:1  p:0 +num[1] ->0
        else if(LL==0&&PP==0){
            P=trie[P][0];
        }//l:0  p:0 ->1
        else if(LL==0&&PP==1){
            P=trie[P][1];
        } //l:0  p:1 ->0
        if(!P)break;
    }
    return ans;
}
signed main(){
    xf_dycm;
    cin>>q;//q次查询
    ll op;
    while(q--){
        cin>>op;
        if(op==1){
            cin>>pi;
            ist(pi);
        }
        else if(op==2){
            cin>>pi;
            dlt(pi);
        }
        else {
            cin>>pi>>li;
            cout<<srh(pi,li)<<endl;
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值