[BZOJ4260] Codechef REBXOR

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=4260

题目大意

给定序列,求最大的 (xl1 xor xl1+1 xor ...xr1)+(xl2 xor xl2+1 xor ...xr2)

题解

xor是支持交换律的,所以我们维护xor前缀和
xl1 xor xl1+1 xor ...xr1=sum[r1]xorsum[l11]
问题变为求 (sum[r1] xor sum[l11])+(sum[l21] xor sum[r2])
sumi,dp[i]:[1,i]
sumTriel2,dpO(1),sum[l21]Trie,
…..我是傻逼,,,,,2^28>10^9

const
  maxn=400005;
var
  x,sum,dp:array[0..maxn]of longint;
  son:array[1..2,0..maxn*31,0..1]of longint;
  i,j,k:longint;
  n,a,tail,ans:longint;
function max(a,b:longint):longint;
begin
  if a<b then exit(b) else exit(a);
end;

procedure init(kind,a:longint);
var i,tt,b:longint;
begin
  tt:=0;
  for i:=30 downto 1 do
    begin
      if (a and (1<<(i-1)))=0
      then b:=0 else b:=1;
      if son[kind,tt,b]=0
      then begin inc(tail); son[kind,tt,b]:=tail; end;
      tt:=son[kind,tt,b];
    end;
end;

function f(kind,a:longint):longint;
var i,tt,b,c,anss:longint;
begin
  tt:=0; anss:=0;
  for i:=30 downto 1 do
    begin
      if (a and (1<<(i-1)))=0
      then b:=0 else b:=1;
      c:=b xor 1;
      if son[kind,tt,c]<>0
      then begin anss:=anss+(1<<(i-1)); tt:=son[kind,tt,c]; end
      else begin tt:=son[kind,tt,b]; end;
    end;
  exit(anss);
end;

begin
  readln(n); sum[0]:=0;
  for i:=1 to n do
    begin
      read(x[i]);
      sum[i]:=sum[i-1] xor x[i];
    end;
  tail:=0;
  for i:=1 to n do
    begin
      init(1,sum[i-1]);
      dp[i]:=max(dp[i-1],f(1,sum[i]));
    end;
  tail:=0; ans:=0;
  for i:=n downto 1 do
    begin
      init(2,sum[i]);
      a:=f(2,sum[i-1]);
      ans:=max(ans,dp[i-1]+a);
    end;
  writeln(ans);
end.

你可能感兴趣的:([BZOJ4260] Codechef REBXOR)