[BZOJ3261] 最大异或和

传送门

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

题目大意

给定序列,支持一下两个操作
1:
2:l,r,x,l<=p<=r,使x  xor  a[p]  xor  a[p+1]  xor  ,...,  xor  a[n]

题解

可持久化Trie树裸题
注意一点,x[0]要插入0,以x[-1]为空节点

const
    maxn=1000005;
var
    x,root:array[0..maxn]of longint;
    son:array[0..30*maxn,0..1]of longint;
    size:array[0..30*maxn]of longint;
    i,j,k:longint;
    n,m,len1,len2,a,b,c:longint;
    cha:char;
procedure init(pre,now,a:longint);
var i,b,c:longint;
begin
    size[now]:=size[pre]+1;
    for i:=29 downto 1 do
        begin
            if (a and (1<<(i-1)))=0
            then b:=0 else b:=1;
            c:=b xor 1;
            son[now,c]:=son[pre,c];
            inc(len2); son[now,b]:=len2;
            size[len2]:=size[son[pre,b]]+1;
            now:=son[now,b];
            pre:=son[pre,b];
        end;
end;

function query(l,r,a:longint):longint;
var i,b,c,tt,val:longint;
begin
    val:=0;
    for i:=29 downto 1 do
        begin
            if (a and (1<<(i-1)))=0
            then b:=0 else b:=1;
            c:=b xor 1;
            tt:=size[son[r,c]]-size[son[l,c]];
            if tt<>0
            then begin l:=son[l,c]; r:=son[r,c]; inc(val,(1<<(i-1))); end
            else begin l:=son[l,b]; r:=son[r,b]; end;
        end;
    exit(val);
end;

begin
    readln(n,m); x[0]:=0; len1:=0; len2:=0;
    for i:=0 to n do
        begin
        if i<>0
            then
                begin
                    inc(len1);
                    read(x[len1]);
                    x[len1]:=x[len1-1] xor x[len1];
                end;
            inc(len2);
            root[len1]:=len2;
            init(root[len1-1],root[len1],x[len1]);
        end;
    readln;
    for i:=1 to m do
        begin
            read(cha);
            if cha='A'
            then
                begin
                    inc(len1);
                    readln(x[len1]);
                    x[len1]:=x[len1-1] xor x[len1];
                    inc(len2);
                    root[len1]:=len2;
                    init(root[len1-1],root[len1],x[len1]);
                end
            else
                begin
                    readln(a,b,c);
                    writeln(query(root[a-2],root[b-1],(x[len1] xor c)));
                end;
        end;
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值