zoukankan      html  css  js  c++  java
  • bzoj 3295 树套树

    比较裸,可以有好多的优化,比如根本没有删除的点没有加在树套树中的必要,预处理

    出来每个不会被删除的值可以减少不少时间,也可以写成树状数组套平衡树,都会快很多

    /**************************************************************
        Problem: 3295
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:11088 ms
        Memory:52180 kb
    ****************************************************************/
     
    //By BLADEVIL
    type
        rec                     =record
            left, right, root   :longint;
        end;
          
    var
        n, m                    :longint;
        high, cur               :array[0..200100] of longint;
        t                       :array[0..300040] of rec;
        b_left, b_right, b_key  :array[0..3000010] of longint;
        b_size                  :array[0..3000010] of longint;
        tot                     :longint;
        ans                     :int64;
          
    procedure swap(var a,b:longint);
    var
        c                       :longint;
    begin
        c:=a; a:=b; b:=c;
    end;
          
    procedure insert(var t:longint;v:longint);
    begin
        if t=0 then
        begin
            inc(tot);
            t:=tot;
            b_size[t]:=1;
            b_left[t]:=0;
            b_right[t]:=0;
            b_key[t]:=v;
        end else
        begin
            inc(b_size[t]);
            if v<b_key[t] then insert(b_left[t],v) else insert(b_right[t],v);
        end;
    end;
      
    function b_delete(var t:longint;v:longint):longint;
    begin
        dec(b_size[t]);
        if (b_key[t]=v) or (v>b_key[t]) and (b_right[t]=0) or (v<b_key[t]) and (b_left[t]=0) then
        begin
            b_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]:=b_delete(b_left[t],v+1);
        end else
            if v>=b_key[t] then exit(b_delete(b_right[t],v)) else exit(b_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,high[i]);
        if l=r then exit;
        with t[x] do mid:=(left+right) div 2;
        build(2*x,l,mid);
        build(2*x+1,mid+1,r);
    end;
      
    function b_less(var t:longint;v:longint):longint;
    begin
        if t=0 then exit(0);
        if b_key[t]>=v then exit(b_less(b_left[t],v)) else
            exit(b_size[b_left[t]]+1+b_less(b_right[t],v));
    end;
      
    function less(x,l,r,v:longint):longint;
    var
        mid                     :longint;
    begin
        if (t[x].left=l) and (t[x].right=r) then
            exit(b_less(t[x].root,v));
        with t[x] do mid:=(left+right) div 2;
        if mid<l then exit(less(2*x+1,l,r,v)) else
        if mid>=r then exit(less(2*x,l,r,v)) else
            exit(less(2*x,l,mid,v)+less(2*x+1,mid+1,r,v));
    end;
      
    function b_greater(var t:longint; v:longint):longint;
    begin
        if t=0 then exit(0);
        if b_key[t]<=v then exit(b_greater(b_right[t],v)) else
            exit(b_size[b_right[t]]+1+b_greater(b_left[t],v));
    end;
      
    function greater(x,l,r,v:longint):longint;
    var
        mid                     :longint;
    begin
        if (t[x].left=l) and (t[x].right=r) then
            exit(b_greater(t[x].root,v));
        with t[x] do mid:=(left+right) div 2;
        if mid<l then exit(greater(2*x+1,l,r,v)) else
        if mid>=r then exit(greater(2*x,l,r,v)) else
            exit(greater(2*x,l,mid,v)+greater(2*x+1,mid+1,r,v));
    end;
      
    procedure change(x,y,v:longint);
    var
        mid                     :longint;
    begin
        insert(t[x].root,v);
        if (t[x].left=t[x].right) then exit;
        with t[x] do mid:=(left+right) div 2;
        if mid<y then change(2*x+1,y,v) else change(2*x,y,v);
    end;
      
    procedure delete(x,y,v:longint);
    var
        mid                     :longint;
    begin
        b_delete(t[x].root,v);
        if (t[x].left=t[x].right) then exit;
        with t[x] do mid:=(left+right) div 2;
        if mid<y then delete(2*x+1,y,v) else delete(2*x,y,v);
    end;
      
    procedure init;
    var
        i                       :longint;
    begin
        read(n,m);
        for i:=1 to n do read(high[i]);
        for i:=1 to n do cur[high[i]]:=i;
        build(1,1,n); 
    end;
      
    procedure main;
    var
        i                       :longint;
        x, y                    :longint;
          
    begin 
        for i:=1 to n-1 do
            ans:=ans+less(1,i+1,n,high[i]);
        for i:=1 to m do
        begin
            writeln(ans);
            read(x);
            y:=cur[x];
            delete(1,y,x);
            if y<>1 then ans:=ans-greater(1,1,y-1,x);
            if y<>n then ans:=ans-less(1,y+1,n,x);
        end;
    end;
      
    begin
        init;
        main;
    end.
  • 相关阅读:
    单点登录的实现原理
    Entity Framework添加记录时获取自增ID值
    linq to entity查询,日期格式化
    Linq之GroupBy用法
    IIS HTTPS CA
    CallContext和多线程
    windows平台 culture name 详细列表
    如何在WCF中集成unity
    .NET MVC 依赖注入 来龙去脉
    apache虚拟主机安装注意事项
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3500179.html
Copyright © 2011-2022 走看看