首页 > 其他 > 详细

bzoj 4260: Codechef REBXOR

时间:2018-02-03 10:24:26      阅读:282      评论:0      收藏:0      [点我收藏+]

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

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!