zoukankan      html  css  js  c++  java
  • HDU 4825 Xor sum

    trie树的异或和问题

    本题是一道经典题,使用trie树维护所给出的集合,我们知道等比数列前n项的和比第n+1项小,所以本题可以使用贪心策略,对于每一个询问,我们从高位向低位匹配,寻找最大异或值,向下递归求解。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #define LL unsigned long long
    using namespace std;
    const int MAXN=3200000+5;
    LL init(){
    	LL rv=0,fh=1;
    	char c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') fh=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		rv=(rv<<1)+(rv<<3)+c-'0';
    		c=getchar();
    	}
    	return fh*rv;
    }
    struct node{
    	int nxt[2];
    }trie[MAXN];
    LL T,n,num,nume,m;
    void ins(const LL id){
    	LL u=0;
    	for(int i=31;i>=0;i--){
    		bool v=(id>>i)&(LL)1;
    		if(!trie[u].nxt[v]) trie[u].nxt[v]=++nume;
    		u=trie[u].nxt[v];
    	}
    }
    LL query(const LL id){
    	LL u=0,ans=0;
    	for(int i=31;i>=0;i--){
    		bool v=(id>>i)&(LL)1;
    		if(trie[u].nxt[!v]){
    			ans=(ans<<1)+!v;
    			u=trie[u].nxt[!v];
    		}else{
    			ans=(ans<<1)+v;
    			u=trie[u].nxt[v];
    		}
    	}
    	return ans;
    }
    int main(){
    	freopen("in.txt","r",stdin);
    	T=init();
    	while(T--){
    		printf("Case #%d:
    ",++num);
    		n=init();m=init();
    		for(int i=1;i<=n;i++){
    			int t=init();
    			ins(t);
    		}
    		for(int i=1;i<=m;i++){
    			int t=init();
    			printf("%d
    ",query(t));
    		}
    		memset(trie,0,sizeof(trie));
    		nume=0;
    	}
    	fclose(stdin);
    	return 0;
    }
    
  • 相关阅读:
    5.9
    5.8
    5.4
    04--深入探讨C++中的引用
    01--Qt扫盲篇
    00--Qt Creator 你必须要掌握的快捷操作
    02--读书笔记之:C++ Primer (第4版)及习题
    01--[转]C++强大背后
    01--数据结构——动态链表(C++)
    04-手把手教你把Vim改装成一个IDE编程环境(图文)
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8010846.html
Copyright © 2011-2022 走看看