未完
静态查询区间第k大
写题发现原来版本众多bug后的最终版本QAQAQ
我说一下主席树的内存怎么开
这个内存啊,我着实分析过,然而QWQ
最后我觉得直接照着题目内存限制开到最大就结了吧~~!
const
maxn=100005;
var
x:array[0..maxn,1..2]of longint;
root,y,z:array[0..maxn]of longint;
w:array[0..20*maxn,1..3]of longint;
i,j,k:longint;
n,m,a,b,c,len,ans: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 build(pre:longint; var now:longint; val,l,r:longint);
var mid:longint;
begin
inc(len); now:=len; mid:=(l+r)>>1;
w[len,3]:=w[pre,3]+1; w[now,2]:=w[pre,2]; w[now,1]:=w[pre,1];
if l=r then exit;
if val<=mid
then build(w[pre,1],w[now,1],val,l,mid)
else build(w[pre,2],w[now,2],val,mid+1,r);
end;
function query(pre,now,k,l,r:longint):longint;
var mid:longint;
begin
if l=r then exit(l);
mid:=(l+r)>>1;
if (w[w[now,1],3]-w[w[pre,1],3])>=k
then exit(query(w[pre,1],w[now,1],k,l,mid))
else exit(query(w[pre,2],w[now,2],k-(w[w[now,1],3]-w[w[pre,1],3]),mid+1,r));
end;
begin
readln(n,m);
for i:=1 to n do
begin
read(x[i,1]);
z[i]:=x[i,1];
x[i,2]:=i;
end;
//--------------------离散化
sort(1,n); {x[i,1]}
for i:=1 to n do
begin
y[i]:=x[i,1];
z[x[i,2]]:=i;
end;
//--------------------离散化
//--------------------建树
root[0]:=0; len:=0;
for i:=1 to n do
build(root[i-1],root[i],z[i],1,n);
//--------------------建树
//--------------------查询
for i:=1 to m do
begin
readln(a,b,c);
ans:=query(root[a-1],root[b],c,1,n);
writeln(y[ans]);
end;
//--------------------查询
end.
经典题就是[BZOJ1176] [Balkan2007]Mokia/[BZOJ2683] 简单题和[BZOJ3262] 陌上花开这两个
mokia那题是有询问和修改的
陌上花开是三维点对的
CDQ要求一定要能离线,在这个各种可持久化满天飞的时候(幸好可持久化Treap还没起来),CDQ还能留有一定席位的~
CDQ常数小,也不难写,结合上树状数组~~