zoukankan      html  css  js  c++  java
  • 2014百度之星第三题Xor Sum(字典树+异或运算)

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xj2419174554/article/details/26083887

    Xor Sum
    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
    Total Submission(s): 4445    Accepted Submission(s): 652

    Problem Description
    Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合。集合中包括了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包括一个正整数 S ,之后 Zeus 须要在集合其中找出一个正整数 K ,使得 K 与 S 的异或结果最大。

    Prometheus 为了让 Zeus 看到人类的伟大,随即允许 Zeus 能够向人类求助。

    你能证明人类的智慧么?
     
    Input
    输入包括若干组測试数据。每组測试数据包括若干行。输入的第一行是一个整数T(T < 10),表示共同拥有T组数据。每组数据的第一行输入两个正整数N。M(<1=N,M<=100000)。接下来一行,包括N个正整数,代表 Zeus 的获得的集合。之后M行。每行一个正整数S,代表 Prometheus 询问的正整数。全部正整数均不超过2^32。

    Output
    对于每组数据,首先须要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1開始计算。

    对于每一个询问,输出一个正整数K,使得K与S异或值最大。


     
    Sample Input
    2
    3 2
    3 4 5
    1
    5
    4 1
    4 6 5 6
    3

    Sample Output
    Case #1:
    4
    3
    Case #2:
    4

     

    题解

        本题数据量非常大。感觉直接暴力时间复杂度O(n*m)会超时,只是想到去年网赛有道题数据量也非常大直接暴力居然过了于是直接敲了敲,终于还是TLE了。

    想到位操作运算符的通用思想,逐位处理,相应本题还是比較easy想到字典树的,Memory Limit: 132768/132768 K (Java/Others)。提示能够尝试牺牲空间换取时间,直接字典树空间消耗为2^32。但本题数据相对此规模还是比較小的,一共n个数,总共32*n位,所以空间复杂度为O(n)。能够接受。

    先用原序列中的数按位建立字典树。然后将查找过程中用待询问数与0xffffffff异或XOR来在字典树上跑。终于找到的即为最大的。如果按查询的XOR的某个分支不存在,则想还有一分支进行,这样答案可能变小,可是正确的,总的时间复杂度O(m*log(32)),常数能够不计。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    const int MAXN=100000*32+100;
    __int64 tree[MAXN][2];
    __int64 node[MAXN];
    __int64 tot;
    
    void insert(__int64 a)
    {
    	__int64 j;
    	int bit,dep=0;
    	for(j=31;j>=0;j--)
    	{
    		bit=((0x1<<j)&a)?0x1:0x0;
    		if(tree[dep][bit]==0)
    		{
    			tree[dep][bit]=tot++;
    			memset(tree[tree[dep][bit]], 0, sizeof(tree[tree[dep][bit]]));
    		}
    		dep=tree[dep][bit];
    	}
    	node[dep]=a;
    }
    
    __int64 Solve(__int64 val)
    {
    	__int64 j,bit;
    	int dep=0;
    	for(j=31;j>=0;j--)
    	{
    		bit=((0x1<<j)&val)?0x0:0x1;
    		if(tree[dep][bit])dep=tree[dep][bit];
    		else dep=tree[dep][bit^1];
    	}
    	return node[dep];
    }
    
    int main()
    {
    	int cas;
    	__int64 n,m,j,s,a;
    	int tag=0;
    	cin>>cas;
    	while(cas--)
    	{
    		tot=1;
    		scanf("%I64d%I64d",&n,&m);
    		memset(tree[0],0,sizeof(tree[0]));
    		while(n--)
    		{
    			scanf("%I64d",&a);
    			
    			insert(a);
    		}
    		printf("Case #%d:
    ",++tag);
    		while(m--)
    		{
    			scanf("%I64d",&s);
    			printf("%I64d
    ",Solve(s));
    		}
    	}
    	return 0;
    }
    


     

     


     


  • 相关阅读:
    JAVA中的super和this关键字的使用
    JAVA中类以及成员变量和成员方法的修饰符的总结
    JAVA中的抽象类和接口
    JAVA对数据库进行操作,实现数据库中数据的插入,查询,更改,删除操作
    完整日期正则表达式
    2017实习【Java研发】面经
    MySQL事务及隔离级别(读书小结)
    Java类编译、加载、和执行机制
    JVM内存回收机制
    Centos6.5的MySQL5.7.15二进制源码单机版安装
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10700731.html
Copyright © 2011-2022 走看看