http://www.lydsy.com/JudgeOnline/problem.php?id=2588
给定一棵树,询问两点间点权第k小的值,强制在线
clj的论文上貌似有这个例题
主席树数组开小了RE了好几次QAQAQ
空间复杂度应该是 O(NlogN)
{$m 10000000}
const
maxn=101000; //0.1
var
y,z,dep,fa,root:array[0..maxn]of longint;
st:array[0..maxn,0..20]of longint;
x:array[0..maxn,1..2]of longint;
t:array[0..3*maxn,1..2]of longint;
w:array[0..20*maxn,1..3]of longint;
i,j,k:longint;
n,m,len,a,b,c,lastans:longint;
procedure sort(l,r:longint);
var i,j,a,b:longint;
begin
i:=l; j:=r; a:=x[(l+r) div 2,1];
repeat
while x[i,1]<a do inc(i);
while a<x[j,1] do dec(j);
if not(i>j) then
begin
b:=x[i,1]; x[i,1]:=x[j,1]; x[j,1]:=b;
b:=x[i,2]; x[i,2]:=x[j,2]; x[j,2]:=b;
inc(i); dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
procedure init(a,b:longint);
begin
t[len,1]:=b;
if t[a,2]=0
then t[a,2]:=len else t[t[a,1],2]:=len;
t[a,1]:=len; inc(len);
end;
function lca(a,b:longint):longint;
var i,j:longint;
begin
if dep[a]>dep[b] then begin i:=a; a:=b; b:=i; end;
for i:=19 downto 0 do
if dep[st[b,i]]>=dep[a]
then b:=st[b,i];
if a=b then exit(a);
for i:=19 downto 0 do
if st[a,i]<>st[b,i]
then begin a:=st[a,i]; b:=st[b,i]; end;
exit(fa[a]);
end;
procedure build(pre,now,val,l,r:longint);
var mid:longint;
begin
mid:=(l+r)>>1; w[now,1]:=w[pre,1]; w[now,2]:=w[pre,2]; w[now,3]:=w[pre,3]+1; inc(len);
if l=r then exit;
if val<=mid
then begin w[now,1]:=len; build(w[pre,1],w[now,1],val,l,mid); end
else begin w[now,2]:=len; build(w[pre,2],w[now,2],val,mid+1,r); end;
end;
function query(a,b,c,d,k,l,r:longint):longint;
var mid,tt:longint;
begin
if l=r then exit(l);
mid:=(l+r)>>1;
tt:=w[w[a,1],3]+w[w[b,1],3]-w[w[c,1],3]-w[w[d,1],3];
if tt>=k
then exit(query(w[a,1],w[b,1],w[c,1],w[d,1],k,l,mid))
else exit(query(w[a,2],w[b,2],w[c,2],w[d,2],k-tt,mid+1,r));
end;
procedure dfs(a:longint);
var tt:longint;
begin
tt:=t[a,2]; inc(len); root[a]:=len;
build(root[fa[a]],root[a],y[a],1,n);
while tt<>0 do
begin
if t[tt,1]<>fa[a]
then
begin
fa[t[tt,1]]:=a;
dep[t[tt,1]]:=dep[a]+1;
st[t[tt,1],0]:=a;
dfs(t[tt,1]);
end;
tt:=t[tt,2];
end;
end;
begin
readln(n,m);
for i:=1 to n do
begin
read(x[i,1]);
x[i,2]:=i;
end;
sort(1,n); {x[i,1]}
for i:=1 to n do
begin
y[x[i,2]]:=i; //离散化后的值
z[i]:=x[i,1]; //原始值
end;
len:=n+1;
for i:=1 to n-1 do
begin
readln(a,b);
init(a,b); init(b,a);
end;
fa[1]:=0; dep[1]:=1; len:=0;
dfs(1);
for j:=1 to 19 do
for i:=1 to n do
st[i,j]:=st[st[i,j-1],j-1];
lastans:=0; fa[0]:=0;
for i:=1 to m do
begin
readln(a,b,k);
a:=a xor lastans;
c:=lca(a,b);
lastans:=query(root[a],root[b],root[c],root[fa[c]],k,1,n);
lastans:=z[lastans];
if i=m
then write(lastans)
else writeln(lastans);
end;
end.