• Codeforces Round #948 (Div. 2) D


    题目链接:http://codeforces.com/contest/948/problem/D

    题意:小花的男朋友是个智障 忘记了加密的密码 那么  就像题目前面的一大堆一样 这两句话是没有用的  给n个数字的a数组和n个数字的p数组 对于每一个a[i]在p数组里选一个数字 两者异或得到新的数组c[i]  为了使得c[i]数组的字典序最小 如何安排a[i]与p[]数组中的那个数字异或呢  p[]数组中的值不能重复使用  输出字典序最小的c[]数组  n的大小为3e5  时间为3.5秒  a[i] p[i]的大小都不超过2^30

    思路:n^2的跑肯定能跑出来 到那时也一定会超时  题目 友善的给出了a[i]和p[i]的大小 那么灵机一动 给p[]的二进制建造一棵树 让a[i]在树上跑 高位尽量为0的时候数字就尽量小了  但是在怎么控制p[]不重复出现的时候遇见了问题  然后想啊想  真是愧对男朋友教我的AC自动机  然后哭腔求助  被告知每个节点记录一下下面有几个单词通过了  如果现在这个节点还有被通过过 那么就继续向下走就行了 然后--  很愉快1A

    ///按照二进制建树  全部建成30层的数  所以要动态建点 不然肯定会爆内存
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    
    using namespace std;
    
    struct NODE
    {
        int node[9000010][2];
        int num[9000010];
        int root , l;///l记录当前的结点个数
        int new_node()
        {
            node[l][0] = -1;
            node[l][1] = -1;
            l++;///根节点的编号是0
            return l-1;
        }
        void init()
        {
            l = 0;
            memset(num , 0 , sizeof(num));
            root = new_node();
        }
        void Insert(int x[])
        {
            int now = root;
            for(int i=0; i<30; i++)
            {
                if(node[now][x[i]]==-1)
                {
                    node[now][x[i]] = new_node();
                }
                now = node[now][x[i]];
                num[now]++;
            }
        }
        int solve(int x[])
        {
            int now = root;
            int res = 0;
            for(int i=0; i<30; i++)
            {
                res = res*2;
                if(node[now][x[i]]!=-1 && num[node[now][x[i]]]!=0)
                {
                    num[node[now][x[i]]]--;
                    now = node[now][x[i]];
                }
                else
                {
                    res++;
                    num[node[now][x[i]^1]]--;
                    now = node[now][x[i]^1];
                }
            }
            return res;
        }
        void debug()
        {
            for(int i=0; i<l; i++)
            printf("%d.......%d....
    " , i , num[i]);
        }
    };
    
    int n;
    int a[300010];
    int b[30];
    NODE trie;
    int num;
    
    int main()
    {
        while( scanf("%d" , &n) != EOF )
        {
            trie.init();
            for(int i=0; i<n; i++)
            {
                scanf("%d" , &a[i]);
            }
            for(int i=0; i<n; i++)
            {
                scanf("%d" , &num);
                memset(b , 0 , sizeof(b));
                int cnt = 29;
                while( num )
                {
                    b[cnt] = num%2;
                    num/=2;
                    cnt--;
                }
                trie.Insert(b);
            }
            for(int i=0; i<n; i++)
            {
                memset(b , 0 , sizeof(b));
                int cnt = 29;
                while( a[i] )
                {
                    b[cnt] = a[i]%2;
                    a[i]/=2;
                    cnt--;
                }
    //            trie.debug();
                if(i)
                printf(" ");
                printf("%d" , trie.solve(b));
            }
            printf("
    ");
        }
    
    
        return 0;
    }
    

      

  • 相关阅读:
    [pixhawk笔记]8-半物理仿真环境
    Python超参数自动搜索模块GridSearchCV上手
    Oriented Response Networks 阅读笔记(一)
    聚类算法评价指标学习笔记
    基于sklearn的常用分类任务指标Python实现
    使用h5py库读写超过内存的大数据
    基于MXNet使用自己的图像数据集训练网络--准备数据与撰写预处理脚本
    在Ubuntu操作系统中添加环境变量
    Jetson TK1 开发板初用体会
    一条脚本搞定OpenCV
  • 原文地址:https://www.cnblogs.com/Flower-Z/p/8591266.html
Copyright © 2020-2023  润新知