使用01字典树解决最大异或问题

问题描述:

Keroro来侵略地球之前,曾跟Giroro伍长打赌:“我一个人灭掉整个地球给你看!”.
于是Keroro同学真的自己一个人来到地球开始他的侵略行动了。从K隆星出发之前,Keroro从Kururu曹长那儿拿了若干台左手武器{Li}和若干台右手武器{Ri},Keroro需要从{Li}里选一台左手武器,从{Ri}里选一台右手武器,用来组合成可用的恐怖武器。
左右手武器组合的规则很简单,假设从{Li}选出来攻击力为p的武器,从{Ri}选出来攻击力为q的武器,组合起来的攻击力就是p XOR q.

 

Keroro想知道,他能组合成的最强武器攻击力为多少?

Hint:必须左右手武器都选出来一个,才能组合成可用武器

XOR表二进制里的“异或”操作,pascal语言里是"xor", C/C++/Java里是"^".

输入

第一行两个整数n, m (1 <= n,m <= 100000), 表有n件左手武器,m件右手武器。
第二行n个正整数{L},li表第i件左手武器的攻击力,0 <= li <= 10^12
第三行m个正整数{R},ri表第i件右手武器的攻击力,0 <= ri <= 10^12

 

思路:

以左手武器的二进制01序列构建字典树。

右手武器按序号依次对字典树进行匹配,贪心发找到异或值最大的分支并更新max。

 

节点类:

class node
{
public:
 node *l,*r;
 int v;
 node()
 {
  l=NULL;
  r=NULL;
 }
};

 

构建字典树(插入序列)

void insert(node * &r,int i,bool *s)
{
 if(i>=42)
  return;
 if(s[i]==0)
 {
  if(r->l==NULL)
  r->l=new node;
  insert(r->l,i+1,s);
 }
 else
 {
  if(r->r==NULL)
  r->r=new node;
  insert(r->r,i+1,s);
 }
}

匹配函数。temp保存最大异或值的01序列。

void  find(bool *s,int i,node *r,bool * &temp)
{
 if(i>=42)
  return;
 if(s[i]==0)
 {
  if(r->r!=NULL)
  {
   temp[i]=1;
   find(s,i+1,r->r,temp);
  }
  else
  {
   temp[i]=0;
   find(s,i+1,r->l,temp);
  }
 }
 if(s[i]==1)
 {
  if(r->l!=NULL)
  {
   temp[i]=1;
   find(s,i+1,r->l,temp);
  }
  else
  {
   temp[i]=0;
   find(s,i+1,r->r,temp);
  }
 }
}

 

主函数略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值