zoukankan      html  css  js  c++  java
  • [trie][异或] hdu 6625 three arrays

    先将题意转换为求A和B中的最小最优异或对并排序输出

    所以可以建两颗trie并同时在两颗树内贪心跳转找最小异或对排序输出

    贪心匹配可以建cnt数组记录当前节点个数,匹配时走过节点个数就直接减一

    最优匹配顺序必然是先相同0 0 , 1 1 再不同 0 1 , 1 0

    完!


    /*
        Zeolim - An AC a day keeps the bug away
    */
     
    //pragma GCC optimize(2)
    #include <bits/stdc++.h>
    #include<queue>
    using namespace std;
    #define mp(x, y) make_pair(x, y)
    #define fr(x, y, z) for(int x = y; x < z; ++x)
    typedef long long ll;
    typedef double ld;
    typedef std::pair<int, int> pii;
    typedef std::vector <short> vi;
    //typedef __int128 ill;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MOD = 1e9 + 7;
    const int MAXN = 2e6 + 10;
    
    int t, n;
    
    int mov[4][2] = { {0, 0},{1, 1},{0, 1}, {1, 0}};
    
    struct Tre
    {
        int trie[MAXN][2], cnt;
        int pre[MAXN];
        void init() 
        {
            fr(i, 0, cnt)
                memset(trie[i], 0, sizeof(trie[i])), pre[i] = 0;
            cnt = 1;
        }
        void insert(ll x)
        {
            int to = 1;
         
            for(int i = 30; i >= 0; --i)
            {
                int val = x >> i & 1;
                if( !trie[to][val])
                    trie[to][val] = ++cnt;
                to = trie[to][val];
                ++pre[to];
            }
        }
    };
    
    int uni(Tre &a, Tre &b)
    {
        int ret = 0;
        int toa = 1, tob = 1;
        for(int i = 30; i >= 0; --i)
        {
            for(int j = 0; j < 4; ++j)
            {
                int pa = mov[j][0], pb = mov[j][1];
                
                if(a.pre[a.trie[toa][pa]] && b.pre[b.trie[tob][pb]])
                {
                    --a.pre[a.trie[toa][pa]], --b.pre[b.trie[tob][pb]];
                    if(j >= 2)
                        ret = ret + (1 << i);
                    toa = a.trie[toa][pa];
                    tob = b.trie[tob][pb];
                    break;
                }
            }
        }
        
        return ret;
    }
    
    int ans[MAXN];
    
    int main()
    {  
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        //freopen("d:out.txt","w",stdout);
        //freopen("in.txt","r",stdin);
        
        cin >> t;
        Tre a, b;
        while(t--)
        {
            cin >> n;
            a.init();
            for(int i = 0, x; i < n; ++i)
            {
                cin >> x;
                a.insert(x);
            }
            b.init();
            for(int i = 0, x; i < n; ++i)
            {
                cin >> x;
                b.insert(x);
            }
            
            fr(i, 0, n)
            {
                ans[i] = uni(a, b);
            }
            
            sort(ans, ans + n);
            
            fr(i, 0, n)
            {
                if(i)
                    cout << ' ';
                cout << ans[i];
            }
            
            cout << '
    ';
        }
        
        return 0;
    }
  • 相关阅读:
    jQuery,from标签,歪路子小技巧
    UniApp随笔
    JS的一些操作
    文本环绕
    Dictionary 存储函数,方法
    GIT项目管理
    Vue2 学习记录
    VSCode + Vue 学习笔记
    Mysql,Insert,Select时自增长问题
    ASP.NET SignalR Troubeshooting
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270353.html
Copyright © 2011-2022 走看看