HDU--4825 Xor Sum (字典树)

题目链接:HDU--4825 Xor Sum

mmp sb字典树因为数组开的不够大一直wa 不是报的 re!!! 找了一下午bug 草

把每个数转化成二进制存字典树里面 然后尽量取与x这个位置上不相同的

先来一个最原始的代码写的跟屎一样的

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<cmath>
#include<vector>
using namespace std;
#define maxn 100010
long long  tot=0;
struct ac{
   long long  sum,fa,nex[3];
   void init(){
     sum=0;fa=0;
     memset(nex,0,sizeof(nex));
   }
}tre[maxn*30];
void add(char a[],long long ii){        // 在这里转化成字符串了
   long long  i=0,j=0,k=0;
   while(a[i]){
       long long  z=a[i]-‘0‘;
       if(tre[k].nex[z]){
          j=tre[k].nex[z];
          tre[j].sum++;
       }else{
          tre[k].nex[z]=++tot;
          j=tot;
          tre[j].init();
          tre[j].sum++;
       }
       k=j;
       i++;
   }
   tre[k].fa=ii;
}
long long  query(char a[]){
   long long  i=0,j=0,k=0;
   long long  s=0;
   while(a[i]){
      long long  z=a[i]-‘0‘;
      if(z==0){
         if(tre[k].nex[1]){
            j=tre[k].nex[1];
         }else j=tre[k].nex[0];
      }else{
         if(tre[k].nex[0]){
            j=tre[k].nex[0];
         }else j=tre[k].nex[1];
      }
      k=j;
      i++;
   }
   return tre[k].fa;
}
long long c[maxn],cnt=0;
void init(){
  tot=0;cnt=0;
  memset(tre,0,sizeof(tre));
}
char a[100],b[100];

int main(){
   long long  t,ant=1;
   scanf("%lld",&t);
   while(t--){
      init();
      long long  n,m;
      scanf("%lld%lld",&n,&m);
      for(long long  j=0;j<n;j++){
         long long  x;
         scanf("%lld",&x);
         c[cnt++]=x;
         long long  len=0;
         while(x){
            long long  i=x%2;
            a[len++]=i+‘0‘;
            x/=2;
         }
         long long  z=len-1;
         for(long long  k=0;k<=32;k++){
           if((32-k)==z){
              b[k]=a[z];
              z--;
           }else b[k]=‘0‘;
         }
         add(b,c[cnt-1]);
      }
      printf("Case #%lld:\n",ant++);
      for(long long  j=0;j<m;j++){
         long long  x;
         scanf("%lld",&x);
         long long  ii=x;
         long long  len=0;
         while(x){
            long long  i=x%2;
            a[len++]=i+‘0‘;
            x/=2;
         }
         long long  z=len-1;
         for(long long  k=0;k<=32;k++){
           if((32-k)==z){
              b[k]=a[z];
              z--;
           }else b[k]=‘0‘;
         }
         long long i=query(b);
         printf("%lld\n",i);
      }
   }
}

改善过后舒心多了

#include<bits/stdc++.h>
using namespace std;
#define maxn 3000000+5
int a[maxn];
int tot;
struct ac{
   int fa,nex[3];
   void init(){
     fa=-1;memset(nex,-1,sizeof(nex));
   }
}tre[maxn];
void add(int x,int y){
  int k=0;
  for(int j=31;j>=0;j--){
     bool z=((1<<j)&x);
     if(tre[k].nex[z]==-1){
        tre[k].nex[z]=++tot;
        tre[tot].init();
     }
     k=tre[k].nex[z];
  }
  //cout<<k<<" "<<y<<endl;
  tre[k].fa=y;
}
int query(int x){
   int k=0;
   for(int j=31;j>=0;j--){
      bool z=((1<<j)&x);
      if(tre[k].nex[z^1]!=-1){
         k=tre[k].nex[z^1];
      }
      else k=tre[k].nex[z];
   }
   return tre[k].fa;
}
void init(){
  memset(tre,0,sizeof(tre));
  tot=0;
  tre[0].init();
}
int main(){
   int t,ant=1;
   cin>>t;
   while(t--){
      init();
      int n,m;
      scanf("%d%d",&n,&m);
      for(int j=0;j<n;j++){
         int x;
         scanf("%d",&x);
         add(x,x);
      }
      printf("Case #%d:\n",ant++);
      for(int j=0;j<m;j++){
         int x;
         scanf("%d",&x);
         printf("%d\n",query(x));
      }
   }
}

原文地址:https://www.cnblogs.com/DyLoder/p/9784222.html

时间: 2024-10-24 18:46:54

HDU--4825 Xor Sum (字典树)的相关文章

HDU 4825 Xor Sum 字典树+位运算

点击打开链接 Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 291    Accepted Submission(s): 151 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus

hdu 4825 xor sum(字典树+位运算)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 4144    Accepted Submission(s): 1810 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

hdu 4825 Xor Sum(字典树)

Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大.Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助.你能证明人类的智慧么? Input 输入包含若干组测试数据,每组测试数据

HDU 4825 Xor Sum(二进制的字典树,数组模拟)

题目 //居然可以用字典树...//用cin,cout等输入输出会超时 //这是从别处复制来的 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int node[3011111][2]; int tag,m,n,cas=0,T; long long one[64],allone,tmp; //0/1树的加数据操作,增加一个32的数 //其中如果当前位是0,则加左儿子,

hdu 4828 Xor Sum (trie 树模板题,经典应用)

hdu 4825 题目链接 题意:给定n个数,然后给出m个询问,每组询问一个数x,问n中的数y使得x和y的异或和最大. 思路:字典树..把每个数转化成二进制,注意补全前导0,使得所有数都有相同的位数. 如果想要异或和最大,那么每一位尽可能都是1. 所以做法是,先构建字典树,然后每次find的时候,尽可能按照和当前寻找的数的位相反的位的方向走(如果有的话) 比如当前位是1,那我就往0的方向走. 需要注意的是,多组数据,每次要重新初始化一遍. 做法是 在struct 中重新 root = new N

hdu 4825 Xor Sum(trie+贪心)

hdu 4825 Xor Sum(trie+贪心) 刚刚补了前天的CF的D题再做这题感觉轻松了许多.简直一个模子啊...跑树上异或x最大值.贪心地让某位的值与x对应位的值不同即可. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #define CLR(a,b) memset((a)

HDU 4825 Xor Sum(经典01字典树+贪心)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 1555    Accepted Submission(s): 657 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

HDU 4825 Xor Sum(01字典树入门题)

http://acm.hdu.edu.cn/showproblem.php?pid=4825 题意: 给出一些数,然后给出多个询问,每个询问要从之前给出的数中选择异或起来后值最大的数. 思路:将给出的数建立01字典树,从高位开始建树.对于每个询问,如果当前位置值为0,那么在字典树中,如果有1的值,那么就优先走1,否则再走0. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using names

HDU - 4825 Xor Sum(01字典树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4825 题目: Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大.Prometheus 为了让 Zeus 看到人类的伟

HDU 4825 Xor Sum 【01字典树】

题面: Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大.Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助.你能证明人类的智慧么? Input 输入包含若干组测试数据,每组