zoukankan      html  css  js  c++  java
  • 923c C. Perfect Security

    Trie树。

    要求字典序最小,所以由前到后贪心的选择。建一个trie树维护b数列。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 300000*(20+5) ;
    const int maxm = 30 + 10;
    
    int a[maxn],s[maxn],p0[maxn],p1[maxn],cnt;
    int n,b;
    
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    void build() {
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1,rhs,t;i<=n;i++) {
            rhs=read();
            t=0;
            for(int j=29;j>=0;j--) 
            {
                b=(rhs>>j&1);
                if(b==0) 
                {
                    if(!p0[t]) p0[t]=++cnt; 
                    t=p0[t];
                }
                else 
                {
                    if(!p1[t]) p1[t]=++cnt; 
                    t=p1[t];
                }
                s[t]++;
            }    
        }
        
        for(int i=1,k,t;i<=n;i++) 
        {
            k=t=0;
            for(int j=29;j>=0;j--) 
            {
                b=(a[i]>>j)&1;
                if(b==0)
                    if(p0[t]&&s[p0[t]]) 
                    {
                        t=p0[t];
                        k*=2;
                        //printf("0");
                    }
                    else
                    {
                        t=p1[t];
                        k=k*2+1;
                        //printf("1");    
                    }
                else 
                {
                    if(p1[t]&&s[p1[t]]) 
                    {
                        t=p1[t];
                        k=k*2+1;    
                    }
                    else 
                    {
                        t=p0[t];
                        k*=2;
                    }
                }
                s[t]--;
            }
            printf("%d ",a[i]^k);
        }
        printf("
    ");
    }
    
    void solve() 
    {
        
    }
    
    int main() 
    {
        build();
        solve();
        
        return 0;
    }
  • 相关阅读:
    欧拉路问题
    树上依赖背包总结
    树状数组的应用
    KMP
    深探树形dp
    再探树形dp
    日常水题
    深入hash
    同一控制下的企业合并,长期股权投资成本与支付账面之间的差额计入资本公积
    资本公积冲减留存收益
  • 原文地址:https://www.cnblogs.com/invoid/p/8646166.html
Copyright © 2011-2022 走看看