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:
",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
",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:
",ant++);
      for(int j=0;j<m;j++){
         int x;
         scanf("%d",&x);
         printf("%d
",query(x));
      }
   }
}