bzoj2733

时间:2023-03-08 19:55:17

好久没写treap,稍微练练
treap的启发式合并

 const key=;
var son:array[..,..] of longint;
root,a,b,fa,count,f:array[..] of longint;
j,n,m,k,x,y,i:longint;
ch:char; function getf(x:longint):longint;
begin
if f[x]<>x then f[x]:=getf(f[x]);
exit(f[x]);
end; procedure update(x:longint);
begin
count[x]:=count[son[x,]]+count[son[x,]]+;
end; procedure rotate(x,w:longint);
var y:longint;
begin
y:=fa[x];
if fa[y]<> then
begin
if son[fa[y],]=y then son[fa[y],]:=x
else son[fa[y],]:=x;
end;
fa[x]:=fa[y];
son[y,-w]:=son[x,w];
if son[x,w]<> then fa[son[x,w]]:=y;
son[x,w]:=y;
fa[y]:=x;
update(y);
update(x);
end; procedure up(i,x:longint);
var j:longint;
begin
j:=fa[i];
while j<> do
begin
if b[i]<b[j] then
begin
if son[j,]=i then rotate(i,)
else rotate(i,);
end
else break;
j:=fa[i];
end;
if fa[i]= then root[x]:=i;
end; procedure insert(x,y:longint);
var p:longint;
begin
b[x]:=trunc(random*key)+;
count[x]:=;
son[x,]:=;
son[x,]:=;
p:=root[y];
repeat
inc(count[p]);
if a[p]>=a[x] then
begin
if son[p,]= then break;
p:=son[p,];
end
else begin
if son[p,]= then break;
p:=son[p,];
end;
until false;
fa[x]:=p;
if a[p]>=a[x] then son[p,]:=x else son[p,]:=x;
up(x,y);
end; procedure succ(x,y:longint);
begin
if son[x,]<> then succ(son[x,],y);
if son[x,]<> then succ(son[x,],y);
insert(x,y);
end; procedure union(x,y:longint);
var k1,k2:longint;
begin
k1:=getf(x);
k2:=getf(y);
if k1<>k2 then
begin
if count[root[k1]]>count[root[k2]] then
begin
f[k2]:=k1;
succ(root[k2],k1);
end
else begin
f[k1]:=k2;
succ(root[k1],k2);
end;
end;
end; function find(k,x:longint):longint;
var p:longint;
begin
p:=root[x];
while p<> do
begin
if count[son[p,]]+=k then exit(p);
if count[son[p,]]+>k then p:=son[p,]
else begin
k:=k-count[son[p,]]-;
p:=son[p,];
end;
end;
exit(-);
end; begin
randomize;
readln(n,k);
for i:= to n do
begin
read(a[i]);
b[i]:=trunc(random*key)+;
f[i]:=i;
root[i]:=i;
end;
for i:= to k do
begin
readln(x,y);
union(x,y);
end;
readln(m);
for i:= to m do
begin
readln(ch,x,y);
if ch='Q' then
begin
x:=getf(x);
writeln(find(y,x));
end
else union(x,y);
end;
end.