zoukankan      html  css  js  c++  java
  • bzoj 3196二逼平衡树 线段树套平衡树

    比较裸的树套树,对于区间K值bz上有一道裸题,详见题解http://www.cnblogs.com/BLADEVIL/p/3455336.html(其实题解也不是很详细)

    //By BLADEVIL
    type
        rec                            =record
            left, right, root        :longint;
        end;
    
    var
        n, m                        :longint;
        a                            :array[0..100100] of longint;
        t                            :array[0..300300] of rec;
        b_left, b_right, b_key        :array[0..1000010] of longint;
        b_size                        :array[0..1000010] of longint;
        tot                            :longint;
        
    function min(a,b:longint):longint;
    begin
        if a>b then min:=b else min:=a;
    end;
    
    function max(a,b:longint):longint;
    begin
        if a>b then max:=a else max:=b;
    end;
        
    procedure left_rotate(var t:longint);
    var
        k                            :longint;
    begin
        k:=b_right[t];
        b_right[t]:=b_left[k];
        b_left[k]:=t;
        b_size[k]:=b_size[t];
        b_size[t]:=b_size[b_left[t]]+b_size[b_right[t]]+1;
        t:=k;
    end;
    
    procedure right_rotate(var t:longint);
    var
        k                            :longint;
    begin
        k:=b_left[t];
        b_left[t]:=b_right[k];
        b_right[k]:=t;
        b_size[k]:=b_size[t];
        b_size[t]:=b_size[b_left[t]]+b_size[b_right[t]]+1;
        t:=k;
    end;
        
    procedure maintain(var t:longint;flag:boolean);
    begin
        if not flag then 
        begin
            if b_size[b_left[b_left[t]]]>b_size[b_right[t]] then 
                right_rotate(t) else 
            if b_size[b_right[b_left[t]]]>b_size[b_right[t]] then 
            begin
                left_rotate(b_left[t]);
                right_rotate(t);
            end else exit;
        end else 
        begin
            if b_size[b_right[b_right[t]]]>b_size[b_left[t]] then 
                left_rotate(t) else 
            if b_size[b_left[b_right[t]]]>b_size[b_left[t]] then 
            begin
                right_rotate(b_right[t]);
                left_rotate(t);
            end else exit;
        end;
        maintain(b_left[t],false);
        maintain(b_right[t],true);
        maintain(t,true);
        maintain(t,false);
    end;
        
    procedure insert(var t:longint;v:longint);
    begin
        if t=0 then 
        begin
            inc(tot);
            t:=tot;
            b_left[t]:=0;
            b_right[t]:=0;
            b_size[t]:=1;
            b_key[t]:=v;
        end else 
        begin
            inc(b_size[t]);
            if v>=b_key[t] then insert(b_right[t],v) else insert(b_left[t],v);
            maintain(t,v>=b_key[t]);
        end;
    end;
    
    function delete(var t:longint; v:longint):longint;
    begin
        dec(b_size[t]);
        if (b_key[t]=v) or (b_key[t]<v) and (b_right[t]=0) or (b_key[t]>v) and (b_left[t]=0) then 
        begin
            delete:=b_key[t];
            if (b_left[t]=0) or (b_right[t]=0) then 
                t:=b_left[t]+b_right[t] else 
                b_key[t]:=delete(b_left[t],v+1);
        end else 
            if v>b_key[t] then delete:=delete(b_right[t],v) else delete:=delete(b_left[t],v);
    end;
    
    procedure build(x,l,r:longint);
    var
        mid                            :longint;
        i                            :longint;
    begin
        t[x].left:=l; t[x].right:=r; t[x].root:=0;
        for i:=l to r do insert(t[x].root,a[i]);
        if l=r then exit;
        with t[x] do mid:=(left+right) div 2;
        build(x*2,l,mid); build(x*2+1,mid+1,r);
    end;
    
    function b_rank(var t:longint;v:longint):longint;
    begin
        if t=0 then exit(0);
        if v<=b_key[t] then 
            b_rank:=b_rank(b_left[t],v) else 
            b_rank:=b_rank(b_right[t],v)+b_size[b_left[t]]+1;
    end;
        
    procedure init;
    var
        i                            :longint;
        
    begin
        read(n,m);
        for i:=1 to n do read(a[i]);
        build(1,1,n);
    end;
    
    function rank(x,l,r,y:longint):longint;
    var
        mid                            :longint;
    begin
        if (t[x].left=l) and (t[x].right=r) then 
        begin
            rank:=b_rank(t[x].root,y);
            exit;
        end;
        with t[x] do mid:=(left+right) div 2;
        if mid<l then rank:=rank(x*2+1,l,r,y) else 
        if mid>=r then rank:=rank(x*2,l,r,y) else 
        rank:=rank(x*2,l,mid,y)+rank(x*2+1,mid+1,r,y);
    end;
    
    procedure askrank(l,r,x:longint);    
    begin
        writeln(rank(1,l,r,x)+1);
    end;
    
    procedure change(x,y,z,c:longint);
    var
        mid                            :longint;
    begin
        mid:=delete(t[x].root,c);
        insert(t[x].root,z);
        if t[x].left=t[x].right then exit;
        with t[x] do mid:=(left+right) div 2;
        if y>mid then change(x*2+1,y,z,c) else 
            change(x*2,y,z,c);
    end;
    
    function b_pred(var t:longint;v:longint):longint;
    begin
        if t=0 then exit(-1);
        if v<=b_key[t] then b_pred:=b_pred(b_left[t],v) else 
        begin
            b_pred:=b_pred(b_right[t],v);
            if b_pred=-1 then b_pred:=b_key[t];
        end;
    end;
    
    function pred(x,l,r,y:longint):longint;
    var
        mid                            :longint;
    begin
        if (t[x].left=l) and (t[x].right=r) then
        begin
            pred:=b_pred(t[x].root,y);
            exit;
        end;
        with t[x] do mid:=(left+right) div 2;
        if mid<l then pred:=pred(x*2+1,l,r,y) else 
        if mid>=r then pred:=pred(x*2,l,r,y) else 
        pred:=max(pred(x*2,l,mid,y),pred(x*2+1,mid+1,r,y));
    end;
    
    procedure askpred(l,r,x:longint);
    begin
        writeln(pred(1,l,r,x));
    end;
    
    function b_succ(var t:longint;v:longint):longint;
    begin
        if t=0 then exit(maxlongint);
        if v>=b_key[t] then b_succ:=b_succ(b_right[t],v) else 
        begin
            b_succ:=b_succ(b_left[t],v);
            if b_succ=maxlongint then b_succ:=b_key[t];
        end;
    end;
    
    function succ(x,l,r,y:longint):longint;
    var
        mid                            :longint;
    begin
        if (t[x].left=l) and (t[x].right=r) then
        begin
            succ:=b_succ(t[x].root,y);
            exit;
        end;
        with t[x] do mid:=(left+right) div 2;
        if mid<l then succ:=succ(x*2+1,l,r,y) else 
        if mid>=r then succ:=succ(x*2,l,r,y) else
            succ:=min(succ(x*2,l,mid,y),succ(x*2+1,mid+1,r,y));
    end;
    
    procedure askselect(a,b,x:longint);
    var
        mid                            :longint;
        ans                            :longint;
        l, r                        :longint;
        xx                            :longint;
    begin
        l:=0; r:=1000000000;
        while l<=r do 
        begin
            mid:=(l+r) div 2;
            xx:=rank(1,a,b,mid)+1;
            if xx<=x then 
            begin
                ans:=mid;
                l:=mid+1;
            end else r:=mid-1;
        end;
        if rank(1,a,b,ans)=x then ans:=succ(1,l,r,ans-1) else ans:=ans;
        writeln(ans);
    end;
    
    procedure asksucc(l,r,x:longint);
    begin
        writeln(succ(1,l,r,x));
    end;
    
    procedure main;
    var
        i                            :longint;
        k, l, r, x                    :longint;
        
    begin
        for i:=1 to m do 
        begin
            read(k);
            if k=1 then 
            begin
                read(l,r,x);
                askrank(l,r,x);
            end else 
            if k=2 then 
            begin
                read(l,r,x);
                askselect(l,r,x);
            end else
            if k=3 then 
            begin
                read(l,x);
                change(1,l,x,a[l]);
                a[l]:=x;
            end else 
            if k=4 then
            begin
                read(l,r,x);
                askpred(l,r,x);
            end else 
            if k=5 then 
            begin
                read(l,r,x);
                asksucc(l,r,x);
            end;
        end;
    end;
    
    begin
        init;
        main;
    end.
  • 相关阅读:
    从验证谈起
    今天感触
    弱点
    经济平衡一些看法
    关于灵魂
    关于博弈论中的一硬币正反问题的分析<二>
    java8新特性:对map集合排序
    junit单元测试不通过报documentationPluginsBootstrapper相关异常
    Maven打包报错:[WARNING] The POM for xxx is missing, no dependency inform
    理解maven命令package、install、deploy的联系与区别
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3464216.html
Copyright © 2011-2022 走看看