zoukankan      html  css  js  c++  java
  • HDU6625 three arrays (字典树+贪心)

    题意

    给定两个长度为1e5的数组a、b,在对a、b数组分别重新排序后,求相同长度的数组c,使得c[i]=a[i] xor b[i],使得数组 c 的字典序最小。

    思路

    分别对a、b建字典树,能走(11/00)就走,否则就走(01/10),找出最小的n个数,从小到大排序之后即为所求数组。

    Code

    #include <bits/stdc++.h>
     
    using namespace std;
    const int maxn = 1e5+10;
    const int maxm = maxn*31;
    int tree[2][maxm][2];
    int num[2][maxm];
    int tot[2];
     
    void insert(int x, int st) {
        int sta[32], top = 0;
        while(x) sta[++top] = x%2, x/=2;
        while(top<30) sta[++top] = 0;
        int ptr = 0;
        for (int x, i=top; i; --i) {
            x = sta[i];
            if(!tree[st][ptr][x]) tree[st][ptr][x] = ++tot[st];
            ++num[st][ptr];
            ptr = tree[st][ptr][x];
        }
        ++num[st][ptr];
    }
    int query() {
        int res = 0, ptr0 = 0, ptr1 = 0;
        for (int i=0; i<30; ++i) {
            res <<= 1;
            if(tree[0][ptr0][1] && tree[1][ptr1][1] && num[0][tree[0][ptr0][1]] && num[1][tree[1][ptr1][1]]) {
                ptr0 = tree[0][ptr0][1];
                ptr1 = tree[1][ptr1][1];
                --num[0][ptr0];
                --num[1][ptr1];
            } else if(tree[0][ptr0][0] && tree[1][ptr1][0] && num[0][tree[0][ptr0][0]] && num[1][tree[1][ptr1][0]]) {
                ptr0 = tree[0][ptr0][0];
                ptr1 = tree[1][ptr1][0];
                --num[0][ptr0];
                --num[1][ptr1];
            } else if(tree[0][ptr0][1] && tree[1][ptr1][0] && num[0][tree[0][ptr0][1]] && num[1][tree[1][ptr1][0]]) {
                ptr0 = tree[0][ptr0][1];
                ptr1 = tree[1][ptr1][0];
                --num[0][ptr0];
                --num[1][ptr1];
                res |= 1;
            } else if(tree[0][ptr0][0] && tree[1][ptr1][1] && num[0][tree[0][ptr0][0]] && num[1][tree[1][ptr1][1]]) {
                ptr0 = tree[0][ptr0][0];
                ptr1 = tree[1][ptr1][1];
                --num[0][ptr0];
                --num[1][ptr1];
                res |= 1;
            }
        }
        return res;
    }
     
    int main() {
        int T, n;
        scanf("%d", &T);
        while(T--) {
            tot[0] = tot[1] = 0;
            scanf("%d", &n);
            for (int i=0; i<=n*31; ++i) {
                tree[0][i][0] = tree[0][i][1] = tree[1][i][0] = tree[1][i][1] = 0;
                num[0][i] = num[1][i] = 0;
            }
            for (int x, i=1; i<=n; ++i) scanf("%d", &x), insert(x, 0);
            for (int x, i=1; i<=n; ++i) scanf("%d", &x), insert(x, 1);
            vector<int> ans;
            for (int i=1; i<=n; ++i) ans.push_back(query());
            sort(ans.begin(), ans.end());
            for (int i=0; i<n; ++i) printf("%d ", ans[i]);
            puts("");
        }
        return 0;
    }
     
    
  • 相关阅读:
    干货 | 日均流量200亿,携程高性能全异步网关实践 https://mp.weixin.qq.com/s/JdbPf_H4pn5PnPH2LIKQlw
    go获取机器的mac地址和ip
    扫清障碍和风险
    如何优雅地记录操作日志
    WebSocket 基础与应用系列(一
    pytest测试框架
    两个循环依赖的类中都有@Async 报错问题
    jvm 分析常用笔记
    Qt5.2~5.8下载地址
    windows的bat脚本中文乱码或者文件中文乱码
  • 原文地址:https://www.cnblogs.com/acerkoo/p/11305472.html
Copyright © 2011-2022 走看看