• bzoj 2151 贪心


      几乎完全类似于1150的思路,直接参考那个就行了。

      http://www.cnblogs.com/BLADEVIL/p/3527193.html

    /**************************************************************
        Problem: 2151
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:3224 ms
        Memory:15092 kb
    ****************************************************************/
     
    //By BLADEVIL
    type
        pointer=^rec;
        rec                     =record
            pred, succ          :pointer;
            num, fuck           :longint;
        end;
        shit                    =record
            shit1, shit2        :longint;
        end;
         
    var
        n, m                    :longint;
        a                       :array[0..200010] of pointer;
        left, right, size       :array[0..400010] of longint;
        key, adr                :array[0..400010] of longint;
        t, tot                  :longint;
        ans                     :longint;
         
    procedure left_rotate(var t:longint);
    var
        k                       :longint;
    begin
        k:=right[t];
        right[t]:=left[k];
        left[k]:=t;
        size[k]:=size[t];
        size[t]:=size[left[t]]+size[right[t]]+1;
        t:=k;
    end;
     
    procedure right_rotate(var t:longint);
    var
        k                       :longint;
    begin
        k:=left[t];
        left[t]:=right[k];
        right[k]:=t;
        size[k]:=size[t];
        size[t]:=size[left[t]]+size[right[t]]+1;
        t:=k;
    end;
     
    procedure maintain(var t:longint;flag:boolean);
    begin
        if not flag then
        begin
            if size[left[left[t]]]>size[right[t]] then
                right_rotate(t) else
            if size[right[left[t]]]>size[right[t]] then
            begin
                left_rotate(left[t]);
                right_rotate(t);
            end else exit;
        end else
        begin
            if size[right[right[t]]]>size[left[t]] then
                left_rotate(t) else
            if size[left[right[t]]]>size[left[t]] then
            begin
                right_rotate(right[t]);
                left_rotate(t);
            end else exit;
        end;
        maintain(left[t],false);
        maintain(right[t],true);
        maintain(t,true);
        maintain(t,false);
    end;
         
    procedure insert(var t:longint;v,k:longint);
    begin
        if t=0 then
        begin
            inc(tot);
            t:=tot;
            left[t]:=0;
            right[t]:=0;
            size[t]:=1;
            key[t]:=v;
            adr[t]:=k;
        end else
        begin
            inc(size[t]);
            if v<key[t] then insert(left[t],v,k) else
            if v>key[t] then insert(right[t],v,k) else
            if v=key[t] then
                if k>adr[t] then insert(right[t],v,k) else
                    insert(left[t],v,k);
            maintain(t,v>=key[t]);
        end;
    end;
     
    function delete(var t:longint;v,k:longint):shit;
    var
        damn                    :shit;
    begin
        dec(size[t]);
        if (v=key[t]) and (k=adr[t]) or (v>key[t]) and (right[t]=0) or (v<key[t]) and (left[t]=0) then
        begin
            delete.shit1:=key[t];
            delete.shit2:=adr[t];
            if (left[t]=0) or (right[t]=0) then
                t:=left[t]+right[t] else
                begin
                    damn:=delete(left[t],v+1,k);
                    key[t]:=damn.shit1;
                    adr[t]:=damn.shit2;
                end;
        end else
            if v<key[t] then delete:=delete(left[t],v,k) else
            if v>key[t] then delete:=delete(right[t],v,k) else
                if v=key[t] then
                    if k>adr[t] then delete:=delete(right[t],v,k) else
                    if k<adr[t] then delete:=delete(left[t],v,k);
    end;
     
    function mini(var t:longint):longint;
    begin
        if right[t]=0 then exit(adr[t]) else exit(mini(right[t]));
    end;
         
    procedure init;
    var
        i                       :longint;
        null                    :pointer;
         
    begin
        read(n,m);
        if m>n>>1 then
        begin
            writeln('Error!');
            halt;
        end;
        for i:=1 to n do
        begin
            new(null);
            a[i]:=null;
            read(a[i]^.num);
        end;
        for i:=1 to n do
        begin
            if i=1 then a[i]^.pred:=a[n] else a[i]^.pred:=a[i-1];
            if i=n then a[i]^.succ:=a[1] else a[i]^.succ:=a[i+1];
        end;
        for i:=1 to n do a[i]^.fuck:=i;
    end;
     
    procedure main;
    var
        i                       :longint;
        x                       :longint;
    begin
        t:=0;
        for i:=1 to n do insert(t,a[i]^.num,i);
        for i:=1 to m do
        begin
            x:=mini(t);
            ans:=ans+a[x]^.num;
            delete(t,a[x]^.num,a[x]^.fuck);
            delete(t,a[x]^.pred^.num,a[x]^.pred^.fuck);
            delete(t,a[x]^.succ^.num,a[x]^.succ^.fuck);
            a[x]^.num:=a[x]^.pred^.num+a[x]^.succ^.num-a[x]^.num;
            insert(t,a[x]^.num,x);
            a[x]^.pred^.pred^.succ:=a[x];
            a[x]^.pred:=a[x]^.pred^.pred;
            a[x]^.succ^.succ^.pred:=a[x];
            a[x]^.succ:=a[x]^.succ^.succ;
        end;
        writeln(ans);
    end;
     
    begin
        init;
        main;
    end.
  • 相关阅读:
    sqlserver,获取调用存储过程返回数据的方法。
    手动为弹窗添加一个阴影背景。
    bootstrap资料链接
    进入Linux救援(rescue)模式的四大法门
    virtual box 5.2.12 扩展包安装
    pypi配置国内开源镜像
    vs2015利用python加载dll调试配置
    ubuntu18安装ubuntu kylin软件中心
    firefox快捷键窗口和标签类
    设置双网卡路由
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3527273.html
Copyright © 2020-2023  润新知