hdu4825-01字典树&&贪心&&经典&&异或最大-Xor Sum

来源:互联网 发布:linux删除文件夹内容 编辑:程序博客网 时间:2024/06/04 19:57

http://acm.hdu.edu.cn/showproblem.php?pid=4825
01字典树可以解决最大异或问题。
把数当成 二进制存到一个 字典树里,不过这个字典树只有0和1,
异或的时候当然要找相反的开始,如果没有再找相同的。
注:记录的时候从高位开始往低位。没有的置0

#include <bits/stdc++.h>#include <cstdio>using namespace std;/* 01字典树,大概就是用字典树的思想把每个数变成 二进制,然后查找,每次尽可能的查找他的相反的。(异或最大)*/struct Node{    int num;//标号上的数    Node *next[2];//指针。};void  add(Node *head,int num){       Node *p=head;       for(int i=31;i>=0;i--){           int k=(num>>i)&1;            //num>>=1;            if(p->next[k]==NULL){                p->next[k]=new Node();                 p=p->next[k];            }            else                p=p->next[k];       }       p->num=num;}int query(Node *head,int sum){     Node *p=head;     for(int i=31;i>=0;i--){         int sign=(sum>>i)&1;          if(p->next[1^sign]==NULL){             p=p->next[sign];          }          else            p=p->next[1^sign];     }   return p->num;}int t,m,n,a;int main(){   scanf("%d",&t);    for(int tt=1;tt<=t;tt++){          scanf("%d%d",&m,&n);          Node *head=new Node();          for(int i=0;i<m;i++){              scanf("%d",&a);              add(head,a);          }          printf("Case #%d:\n",tt);          for(int i=0;i<n;i++){              scanf("%d",&a);              printf("%d\n",query(head,a));          }    }    return 0;}
原创粉丝点击