码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 4260: Codechef REBXOR

时间:2018-02-03 12:44:57      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:const   com   --   solution   using   stdout   return   xor   技术分享   

Description

技术分享图片

Solution

记录前缀答案和后缀答案,然后枚举断点合并即可
求出以每一个结尾的最大异或的段,相当于求两个前缀异或值的最大值,用trie树贪心即可

#include<bits/stdc++.h>
using namespace std;
const int N=400005;
int n,a[N],f[N],bin[N],rt=0,ch[N*30][2],cnt=0;
inline int qry(int x,int d,int v){
  if(d==-1)return 0;
  if(v&bin[d]){
    if(ch[x][0])return qry(ch[x][0],d-1,v)|bin[d];
    return qry(ch[x][1],d-1,v);
  }
  else{
    if(ch[x][1])return qry(ch[x][1],d-1,v)|bin[d];
    return qry(ch[x][0],d-1,v);
  }
}
inline void ins(int &x,int d,int v){
  if(!x)x=++cnt;
  if(d==-1)return ;
  ins(ch[x][(v&bin[d])>0],d-1,v);
}
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  scanf("%d",&n);
  for(int i=1;i<=n;i++)scanf("%d",&a[i]);
  bin[0]=1;for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1;
  int sum=0,ans=0;
  ins(rt,30,0);
  for(int i=1;i<=n;i++){
    sum^=a[i];
    f[i]=max(f[i-1],qry(rt,30,sum));
    ins(rt,30,sum);
  }
  sum=0;rt=0;cnt=0;
  memset(ch,0,sizeof(ch));
  ins(rt,30,0);
  for(int i=n;i>=2;i--){
    sum^=a[i];
    ans=max(ans,f[i-1]+qry(rt,30,sum));
    ins(rt,30,sum);
  }
  printf("%d\n",ans);
  return 0;
}

bzoj 4260: Codechef REBXOR

标签:const   com   --   solution   using   stdout   return   xor   技术分享   

原文地址:https://www.cnblogs.com/Yuzao/p/8408590.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!