题意:N个点,每个点有一个权值,支持四种操作:
(1)询问x到y的路径上的点的权值xor和
(2)连接x到y
(3)删除边(x,y)
(4)将x的权值改成y
LCT维护一下即可
var
n,m,op,x,y :longint;
i :longint;
w :array[0..300010] of longint;
father,sum :array[-1..300010] of longint;
son :array[-1..300010,0..1] of longint;
flag :array[-1..300010] of boolean;
procedure swap(var a,b:longint);
var
c:longint;
begin
c:=a; a:=b; b:=c;
end;
function root(x:longint):boolean;
begin
if (x=son[father[x],0]) or (x=son[father[x],1]) then exit(false);
exit(true);
end;
procedure update(x:longint);
begin
sum[x]:=sum[son[x,0]] xor sum[son[x,1]] xor w[x];
end;
procedure renew(x:longint);
begin
flag[x]:=not flag[x];
end;
procedure push_down(x:longint);
begin
if flag[x] then
begin
swap(son[x,0],son[x,1]);
if son[x,0]<>-1 then flag[son[x,0]]:=not flag[son[x,0]];
if son[x,1]<>-1 then flag[son[x,1]]:=not flag[son[x,1]];
flag[x]:=false;
end;
end;
procedure push(x:longint);
begin
if not root(x) then push(father[x]);
push_down(x);
end;
procedure ro(x,y:longint);
var
f:longint;
begin
f:=father[x];
if son[x,y xor 1]<>-1 then father[son[x,y xor 1]]:=f;
son[f,y]:=son[x,y xor 1];
if f=son[father[f],0] then son[father[f],0]:=x else
if f=son[father[f],1] then son[father[f],1]:=x;
father[x]:=father[f];
son[x,y xor 1]:=f;
father[f]:=x;
update(f);
update(x);
end;
procedure splay(x:longint);
var
u,v:longint;
begin
while not root(x) do
begin
if root(father[x]) then ro(x,ord(x=son[father[x],1])) else
begin
if x=son[father[x],0] then u:=-1 else u:=1;
if father[x]=son[father[father[x]],0] then v:=-1 else v:=1;
if u*v=1 then
begin
ro(father[x],ord(x=son[father[x],1]));
ro(x,ord(x=son[father[x],1]));
end else
begin
ro(x,ord(x=son[father[x],1]));
ro(x,ord(x=son[father[x],1]));
end;
end;
end;
update(x);
end;
procedure access(x:longint);
var
y:longint;
begin
y:=-1;
while x<>0 do
begin
push(x);
splay(x);
son[x,1]:=y;
update(x);
y:=x;
x:=father[x];
end;
end;
function find_root(x:longint):longint;
begin
access(x); splay(x);
while son[x,0]<>-1 do x:=son[x,0];
exit(x);
end;
begin
read(n,m);
fillchar(son,sizeof(son),255);
for i:=1 to n do read(w[i]);
for i:=1 to n do sum[i]:=w[i];
for i:=1 to m do
begin
read(op,x,y);
if op=0 then
begin
access(x); splay(x); renew(x);
access(y); splay(y);
writeln(sum[y]);
end else
if op=1 then
begin
if find_root(x)<>find_root(y) then
begin
access(x); splay(x); renew(x);
access(y); splay(y);
son[y,1]:=x;
father[x]:=y;
end;
end else
if op=2 then
begin
if find_root(x)=find_root(y) then
begin
access(x); splay(x); renew(x);
access(y); push(x); splay(x);
if father[y]=x then
begin
son[x,1]:=-1;
father[y]:=0;
end;
end;
end else
begin
access(x); splay(x); renew(x);
w[x]:=y;
update(x);
end;
end;
end.
——by Eirlys