题目: | 异或密码 | |
来源: | Tyvj 1512 | |
题目大意: | 给出原码组,以及每次查询的对应数和修改情况,希望你可以给出每次密码的值。密 码是异或出来的 P=1,修改 P=0,查询 | |
数据范围: | n<=50000 m<=100000 | |
样例: | 5 3 3 9 6 0 3 0 2 2 1 1 2 0 2 4 | 9 15 |
做题思路: | 自从做了忠诚2,线段树代码得心应手(ctrl c ctrl v),把忠诚的参数改改交了哈。。 | |
知识点: | 线段树 |
const MaxN=100010;
type
tre=record
l,r,lc,rc,min:longint;{<这个min不是min而是异或后的值,只不过我没给他名字因为懒哈。。>}
end;//tre
var
tree:array[0..MaxN*4] of tre;
n,m,i,j,x,a,b,root,tot,ans,p:longint;
procedure build(var t:longint;l,r:longint);
begin
inc(tot);t:=tot;
tree[t].l:=l;tree[t].r:=r;
tree[t].min:=maxlongint;
ifl<r then
begin
build(tree[t].lc,l,(l+r)div2);
build(tree[t].rc,(l+r)div 2+1,r);
end;//if
end;
procedure insert(t,i:longint);
begin
if t=0then exit;
iftree[t].l=tree[t].r then
begin
tree[t].min:=x;
exit;
end;
iftree[tree[t].lc].r>=i then insert(tree[t].lc,i)
elseinsert(tree[t].rc,i);
tree[t].min:=tree[tree[t].lc].min xortree[tree[t].rc].min;
end;
procedure find(t,l,r:longint);
begin
if t=0then exit;
if(tree[t].l=l)and(tree[t].r=r) then
begin
ans:=ansxor tree[t].min;
exit;
end;
iftree[tree[t].lc].r>=r then find(tree[t].lc,l,r)
else
iftree[tree[t].rc].l<=l then find(tree[t].rc,l,r)
else
begin
find(tree[t].lc,l,tree[tree[t].lc].r);
find(tree[t].rc,tree[tree[t].rc].l,r);
end;
end;
begin
readln(m,n);
root:=0;tot:=0;
build(root,1,m);
fori:=1 to m do
begin
read(x);
insert(root,i);
end;
fori:=1 to n do
begin
readln(p,a,x);
ifp=0 then
begin
ans:=0;
find(root,a,x);
write(ans,' ');
end
else
begin
insert(root,a);
end;
end;
end.
题目来源:
http://www.tyvj.cn:8080/Problem_Show.asp?id=1512