P3369 【模板】普通平衡树

这道题最简单的解法: 权值线段树

  • 代码行数: \(48\)

  • 难度: \(Splay\)\(\frac{1}{10}\) 不到。

下面的程序为了方便大家理解没有离散化哦。

操作 \(I\) / \(II\): 插入 / 删除 \(x\)

直接写一个 \(Change\) 函数代表在线段树的 \(x\) 这个位置 \(±1\)

procedure Change(l,r,k,key,add:longint);
var mid:longint;
begin
    inc(tree[k],add); if l=r then exit;
    mid:=(l+r) >> 1;
    if key<=mid then Change(l,mid,k << 1,key,add)
    else Change(mid+1,r,k << 1+1,key,add);
end;

操作 \(III\): 查询 \(x\) 数的排名

利用第 \(K\) 大的方法,可以发现我们在权值线段树中往右跑的时候应该加上左儿子的权值。最后到了要加上自己的一名。

function Query_number_rank(l,r,k,key:longint):longint;
var mid:longint;
begin
    Query_number_rank:=0;
    if l=r then exit(1);
    mid:=(l+r) >> 1;
    if key<=mid then inc(Query_number_rank,Query_number_rank(l,mid,k << 1,key)) else
    begin inc(Query_number_rank,tree[k << 1]); inc(Query_number_rank,Query_number_rank(mid+1,r,k << 1+1,key)); end;
end;

操作 \(IV\): 查询排名为 \(x\) 的数

直接查询第 \(K\) 大就好啦。

function Query_rank_number(l,r,k,key:longint):longint;
var mid:longint;
begin
    if l=r then exit(l);
    mid:=(l+r) >> 1;
    if tree[k << 1]>=key then Query_rank_number:=Query_rank_number(l,mid,k << 1,key)
    else Query_rank_number:=Query_rank_number(mid+1,r,k << 1+1,key-tree[k << 1]);
end;

操作 \(V\): 求 \(x\) 的前驱

\(x\) 的前驱可以转化为找 \(rank[x]-1\) 的数什么,然后直接搞。

if order=5 then writeln(Query_rank_number(1,border,1,Query_number_rank(1,border,1,k)-1));

操作 \(VI\): 求 \(x\) 的后继

考虑到直接像 \(V\) 一样查后继可能是数本身 (如果有很多个同样的数字),那么我们可以记录一下每一个数字的出现次数为 \(bucket[x]\),然后直接搞。

if order=6 then writeln(Query_rank_number(1,border,1,Query_number_rank(1,border,1,k)+bucket[k]));

\(Code\)

离散化后的 \(100\) 分。(这数据强度真的是醉了)

var
	num,sortn,order:array[-1..110000] of longint;
    dis:array[-11000000..11000000] of longint;
    recf,bucket:array[-1..110000] of longint;
    tree:array[-1..810000] of longint;
    i,k,n,head,tail,border:longint;

procedure Swap(var x,y:longint);var t:longint; begin t:=x; x:=y; y:=t; end;

procedure Sort(l,r:longint);
var i,j,s:longint;
begin
    i:=l; j:=r; s:=sortn[(l+r) >> 1];
    repeat
        while sortn[i]<s do inc(i);
        while sortn[j]>s do dec(j);
        if i<=j then begin Swap(sortn[i],sortn[j]); inc(i); dec(j); end;
    until i>=j;
    if i<r then Sort(i,r);
    if j>l then Sort(l,j);
end;

procedure Change(l,r,k,key,add:longint);
var mid:longint;
begin
    inc(tree[k],add); if l=r then exit;
    mid:=(l+r) >> 1;
    if key<=mid then Change(l,mid,k << 1,key,add)
    else Change(mid+1,r,k << 1+1,key,add);
end;

function Query_number_rank(l,r,k,key:longint):longint;
var mid:longint;
begin
    Query_number_rank:=0;
    if l=r then exit(1);
    mid:=(l+r) >> 1;
    if key<=mid then inc(Query_number_rank,Query_number_rank(l,mid,k << 1,key)) else
    begin inc(Query_number_rank,tree[k << 1]); inc(Query_number_rank,Query_number_rank(mid+1,r,k << 1+1,key)); end;
end;

function Query_rank_number(l,r,k,key:longint):longint;
var mid:longint;
begin
    if l=r then exit(l);
    mid:=(l+r) >> 1;
    if tree[k << 1]>=key then Query_rank_number:=Query_rank_number(l,mid,k << 1,key)
    else Query_rank_number:=Query_rank_number(mid+1,r,k << 1+1,key-tree[k << 1]);
end;

begin
    read(n);
    for i:=1 to n do begin  read(order[i],num[i]); if (order[i]<=2)or(order[i]>=5) then begin inc(head); sortn[head]:=num[i]; end; end;
    Sort(1,head);
    for i:=1 to head do if sortn[i]<>sortn[i-1] then begin inc(tail); dis[sortn[i]]:=tail; recf[tail]:=sortn[i]; end;
    border:=tail;
    for i:=1 to n do
    begin
        if order[i]=1 then begin inc(bucket[dis[num[i]]]); Change(1,border,1,dis[num[i]],1); end;
        if order[i]=2 then begin dec(bucket[dis[num[i]]]); Change(1,border,1,dis[num[i]],-1); end;
        if order[i]=3 then writeln(Query_number_rank(1,border,1,dis[num[i]]));
        if order[i]=4 then writeln(recf[Query_rank_number(1,border,1,num[i])]);
        if order[i]=5 then writeln(recf[Query_rank_number(1,border,1,Query_number_rank(1,border,1,dis[num[i]])-1)]);
        if order[i]=6 then writeln(recf[Query_rank_number(1,border,1,Query_number_rank(1,border,1,dis[num[i]])+bucket[dis[num[i]]])]);
    end;
end.
posted @ 2019-01-25 21:49  _ARFA  阅读(110)  评论(0编辑  收藏  举报