C - 秋实大哥与快餐店

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

朝为田舍郎,暮登天子堂。秋实大哥从小就怀抱有远大的理想,所以他开了一家快餐店。

秋实大哥根据菜的口感,给每一道菜一个唯一的CID,同时对于前来的客人,根据他们的口味喜好,秋实大哥会给每一个客人一个PID

对于一个标号为PID的客人,他对标号为CID的菜的喜爱程度为PIDCID(表示按位异或),该值越大表示越喜欢。

秋实大哥实在太忙了,现在他需要你来帮忙照看一下他的店铺。

Input

第一行包含一个整数n,表示秋实大哥的餐馆内现在有n道菜。

接下来一行包含n个整数,分别表示每一道菜的CID

接下来一行包含一个整数m,表示接下来发生了m件事。

接下来的m行,每一行为以下两种事件之一:

0 c : 表示秋实大哥最新研制出一道标号为c的菜
1 p : 表示来了一位标号为p的客人,请你在已有的菜中找出一道他最喜爱的菜

1nm1000000PIDCID1000000

Output

对于每一个1 p事件输出一个整数,表示该客人最喜欢的菜的标号。

Sample input and output

Sample InputSample Output
1
1
3
1 1
0 2
1 1
1
2

 

解题报告

首先注意到异或的特性是相同为0,不同为1。其次注意到二进制数的特点为最高位优势,即对于任何一个二进制数,一旦其某个高位为1,那么自该高位之后的所有位皆为1也无法比其大.

因此我们采用字典树来保存每个数的每位二进制数,离根近的为高位,查询的时候采用贪心走法即可.

 

#include <iostream>
#include <cstring>
using namespace std;

/*
log2 1e6 向上取整为20,即树的高度小于等于21,使用满二叉树来进行存储,2^22
*/
const int maxbit = 20;

typedef struct data
{
  char l,r;    
  int  id;
};

data tree[(1<<22) + 50],n;

void insert(int x)
{
  int ptr = 1,cur = 0;
  while(cur < maxbit)
   {
         if (x >> (maxbit-cur-1) & 1)
          {
                tree[ptr].r = 1;
                ptr = ptr*2+1;
       }
         else
          {
                tree[ptr].l = 1;
                ptr <<= 1;
       }
      cur++;
   }
  ptr <<= 1;
  tree[ptr].id = x;
}

int find(int x)
{
   int ptr = 1 , cur = 0 , tar = ~x;
   while(cur < maxbit)
    {
       if ( (tar >> (maxbit-cur-1) ) & 1)
        {
          if (tree[ptr].r)
           ptr = ptr*2+1;
          else
           ptr <<= 1; 
        }
       else    
        {
           if (tree[ptr].l)
            ptr <<= 1;
           else
            ptr = ptr*2+1;
            
        }
       cur++;
    }
   ptr <<= 1;
   return tree[ptr].id;
}


int main(int argc,char *argv[])
{
  int n,m;
  memset(tree,0,sizeof(tree));
  scanf("%d",&n);
  for(int i = 0 ; i < n ; ++ i)
   {
         int temp;
         scanf("%d",&temp);
         insert(temp);
   }
  scanf("%d",&m);
  while(m--)
   {
         int i,j;
         scanf("%d%d",&i,&j);
         if (i & 1)
          printf("%d\n",find(j));
      else
       insert(j);
   }
  return 0;
}

 

posted on 2015-05-01 01:14  天心散人  阅读(205)  评论(0编辑  收藏  举报