[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 << '\n';
    }
    
    return 0;
}

 

posted @ 2019-08-07 09:29  张浦  阅读(82)  评论(0编辑  收藏  举报