BZOJ3261 最大异或和 (可持久化Trie)

const maxn=600008;
      len=24;
var x,y,z,n,m,tot,lx,i:longint;
    sum:array[0..maxn] of longint;
    rt:array[0..maxn] of longint;
    time,l,r:array[0..maxn*len] of longint;
    ch:char;
procedure insert(x:longint);inline;
var p,i:longint;
begin
    rt[lx]:=tot+1; p:=rt[lx-1];
    for i:=len downto 1 do
    begin
        inc(tot); l[tot]:=l[p]; r[tot]:=r[p]; time[tot]:=time[p]+1;
        if (x and (1<<(i-1))) >0 then
        begin
            p:=r[p];
            r[tot]:=tot+1;
        end else
        begin
            p:=l[p];
            l[tot]:=tot+1;
        end;
    end;
    inc(tot); l[tot]:=l[p]; r[tot]:=r[p]; time[tot]:=time[p]+1;
end;
function query(a,b,x:longint):longint;inline;
var ans,i:longint;
begin
    ans:=0;
    for i:=len downto 1 do
    begin
        if (x and (1<<(i-1))) >0 then
        begin
            if time[l[b]]>time[l[a]] then
            begin
                a:=l[a]; b:=l[b];
                ans:=ans+1<<(i-1);
            end
            else
            begin
                a:=r[a]; b:=r[b];
            end
        end else
        begin
            if time[r[b]]>time[r[a]] then
            begin
                a:=r[a]; b:=r[b];
                ans:=ans+1<<(i-1);
            end
            else
            begin
                a:=l[a]; b:=l[b];
            end
        end;
    end;
    exit(ans);
end;
begin
    readln(n,m);
    sum[0]:=0; lx:=1;
    insert(0);
    for i:=1 to n do
    begin
                read(x);
        inc(lx);
        sum[lx]:=x xor sum[lx-1];
        insert(sum[lx]);
    end;
    readln;
    for i:=1 to m do
    begin
        read(ch);
        if ch='A' then
        begin
            readln(x);
            inc(lx);
            sum[lx]:=x xor sum[lx-1];
            insert(sum[lx]);
        end else
        begin
            readln(x,y,z);
            writeln(query(rt[x-1],rt[y],z xor sum[lx]));
        end;
    end;
end.
        

 

posted @ 2015-03-20 16:59  rpSebastian  阅读(198)  评论(0编辑  收藏  举报