主席树+CDQ分治+整体二分

未完

主席树

静态查询区间第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.

CDQ分治

经典题就是[BZOJ1176] [Balkan2007]Mokia/[BZOJ2683] 简单题和[BZOJ3262] 陌上花开这两个
mokia那题是有询问和修改的
陌上花开是三维点对的
CDQ要求一定要能离线,在这个各种可持久化满天飞的时候(幸好可持久化Treap还没起来),CDQ还能留有一定席位的~
CDQ常数小,也不难写,结合上树状数组~~

你可能感兴趣的:(主席树+CDQ分治+整体二分)