Perfect Security (01字典树&&删除点)

Perfect Security

https://ac.nowcoder.com/acm/problem/112567

题意:
第一行给你一个n
第二行给你n个数字 分别是a[1],a[2].....a[n]。
第三行给你n个数字 分别是b[1],b[2].....b[n]。

问:第三行的序列可自由排列,要求排列之后的顺序 a[1]^b[1],a[2]^b[2]...a[n]^b[n]的字典序最小。

题解:
因为b数组可以自由排列,那么我们把b数组先生成一个字典序。
要想字典序最小,那么根据贪心的思想,我们a[1]要与b中的某个数异或后值最小。
那么我们再遍历一遍a数组每次找出当前能组合的最小值。

因为每次组合后,我们需要删除b中一个元素,那么b已经是字典树了,怎么删?
我们用一个size数组来记录这个数出现的次数,和一个fa数组记录当前结点的父亲结点。
当size[node]=0的时候,这个数字也就没了,就该删除这个结点了。(因为可能会出现重复数组)
递归往上删除,如果当前节点删除,他的父节点只有它一个孩子,那么该父节点也需要删除,重复操作即可!
代码:

/*Keep on going Never give up*/
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>

//#define int long long
#define endl '\n'
#define Accepted 0
#define AK main()
#define I_can signed
using namespace std;
const int maxn =1e7+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
using namespace std;

int trie[maxn][2],sz[maxn],fa[maxn];
int cnt;
int a[500000];

void ins(int x){
    int node=0;
    for(int i=31;i>=0;i--){
        int t=(x>>i)&1;
        if(!trie[node][t]){
            trie[node][t]=++cnt;
            fa[cnt]=node;
        }
        node=trie[node][t];
    }
    sz[node]++;
}

int quer(int x){
    int res=0,node=0;
    for(int i=31;i>=0;i--){
        int t=(x>>i)&1;
        if(trie[node][t]){
            node=trie[node][t];
        }
        else{
            node=trie[node][t^1];
            res|=(1<<i);
        }
    }
    if((--sz[node])==0){
        while(node){
            int f=fa[node],b;

            if(trie[f][1]==node) b=1;
            else b=0;
            trie[f][b] = 0;
            trie[node][b]=0;
            if(trie[f][b^1]) break;
            node=f;
        }
    }
    return res;
}

signed main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
        //ins(a[i]);
    }
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        ins(x);
    }
    for(int i=0;i<n;i++){
        cout<<quer(a[i])<<" ";
    }

    return 0;
}

题解 文章被收录于专栏

主要写一些题目的题解

全部评论

相关推荐

01-21 12:26
暨南大学 golang
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
正在热议
更多
# 听劝,这个简历怎么改 #
14086次浏览 182人参与
# 面试被问“你的缺点是什么?”怎么答 #
6359次浏览 98人参与
# 水滴春招 #
16345次浏览 346人参与
# 入职第四天,心情怎么样 #
11310次浏览 63人参与
# 租房找室友 #
8021次浏览 53人参与
# 读研or工作,哪个性价比更高? #
26151次浏览 356人参与
# 职场新人生存指南 #
199185次浏览 5509人参与
# 参加完秋招的机械人,还参加春招吗? #
26977次浏览 276人参与
# 文科生还参加今年的春招吗 #
4108次浏览 31人参与
# 简历无回复,你会继续海投还是优化再投? #
48619次浏览 561人参与
# 你见过最离谱的招聘要求是什么? #
144719次浏览 829人参与
# 如果重来一次你还会读研吗 #
155714次浏览 1706人参与
# 机械人选offer,最看重什么? #
69077次浏览 449人参与
# 选择和努力,哪个更重要? #
44292次浏览 493人参与
# 如果再来一次,你还会学硬件吗 #
103645次浏览 1245人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
20520次浏览 413人参与
# 招聘要求与实际实习内容不符怎么办 #
46727次浏览 494人参与
# 22届毕业,是读研还是拿外包offer先苟着 #
4652次浏览 27人参与
# 你们的毕业论文什么进度了 #
901211次浏览 8960人参与
# 软开人,你觉得应届生多少薪资才算合理? #
81371次浏览 496人参与
# 国企还是互联网,你怎么选? #
109189次浏览 853人参与
牛客网
牛客企业服务