传送门
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[l1−1]
问题变为求
(sum[r1] xor sum[l1−1])+(sum[l2−1] xor sum[r2])
我们从前向后插入sum枚举i,得到dp[i]:[1,i]中最大抑或段
然后再从后向前把sum添加进新的Trie并枚举l2,第一个区间通过dp值O(1)查询,第二个区间把sum[l2−1]放到新的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.