zoukankan      html  css  js  c++  java
  • 【CodeForces】947 C. Perfect Security 异或Trie

    【题目】C. Perfect Security

    【题意】给定长度为n的非负整数数组A和数组B,要求将数组B重排列使得A[i]^B[i]的字典序最小。n<=3*10^5,time=3.5s。

    【算法】异或Trie

    【题解】对一个数组O(n log n)建立异或Trie,就能O(log n)判断任意一个数在这个数组中异或值最大的数

    所以对B建异或Trie(每个数字从高二进制位开始插入),然后数组A依次在Trie上跑,从上到下尽量跑向相同数字边,这样得到字典序最小,路径中顺便删除标记。

    复杂度O(n log n)。

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<set>
    #include<vector>
    #include<algorithm>
    #define ll long long
    #define lowbit(x) x&-x
    using namespace std;
    int read(){
        char c;int s=0,t=1;
        while(!isdigit(c=getchar()))if(c=='-')t=-1;
        do{s=s*10+c-'0';}while(isdigit(c=getchar()));
        return s*t;
    }
    int min(int a,int b){return a<b?a:b;}
    int max(int a,int b){return a<b?b:a;}
    int ab(int x){return x>0?x:-x;}
    //int MO(int x){return x>=MOD?x-MOD:x;}
    //void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
    /*------------------------------------------------------------*/
    const int inf=0x3f3f3f3f,maxn=300010;
    int ch[maxn*30][2],sz,num[maxn*30*2],a[maxn];
    
    int n;
    void insert(int y){
        int x=0;
        for(int i=29;i>=0;i--){
            bool k=(y&(1<<i))>0;
            if(!ch[x][k])ch[x][k]=++sz;
            num[ch[x][k]]++;
            x=ch[x][k];
        }
    }
    int find(int y){
        int x=0;
        for(int i=29;i>=0;i--){
            bool k=(y&(1<<i))>0;
            if(num[ch[x][k]]>0){
                x=ch[x][k];
                num[x]--;
                y^=((k)<<i);
            }
            else{
                x=ch[x][!k];
                num[x]--;
                y^=((!k)<<i);
            }
        }
        return y;
    }        
    int main(){
        n=read();
        for(int i=1;i<=n;i++)a[i]=read();
        for(int i=1;i<=n;i++)insert(read());
        for(int i=1;i<=n;i++)printf("%d ",find(a[i]));
        return 0;
    }
    View Code
  • 相关阅读:
    LeetCode "Palindrome Partition II"
    LeetCode "Longest Substring Without Repeating Characters"
    LeetCode "Wildcard Matching"
    LeetCode "Best Time to Buy and Sell Stock II"
    LeetCodeEPI "Best Time to Buy and Sell Stock"
    LeetCode "Substring with Concatenation of All Words"
    LeetCode "Word Break II"
    LeetCode "Word Break"
    Some thoughts..
    LeetCode "Longest Valid Parentheses"
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8545459.html
Copyright © 2011-2022 走看看