zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    delphi 字符串查找替换函数 转
    Delphi流的操作
    【BZOJ1316】树上的询问 点分治+set
    【BZOJ2406】矩阵 二分+有上下界的可行流
    【BZOJ1853/2393】[Scoi2010]幸运数字/Cirno的完美算数教室 DFS+容斥
    【BZOJ4999】This Problem Is Too Simple! 离线+树状数组+LCA
    【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包
    【BZOJ3217】ALOEXT 替罪羊树+Trie树
    【BZOJ1336】[Balkan2002]Alien最小圆覆盖 随机增量法
    【BZOJ3435】[Wc2014]紫荆花之恋 替罪点分树+SBT
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3527273.html
Copyright © 2011-2022 走看看