bzoj 1150 [CTSC2007]数据备份Back…

来源:互联网 发布:联合国一票否决权 知乎 编辑:程序博客网 时间:2024/06/03 10:27

Description

bzoj <wbr>1150 <wbr>[CTSC2007]数据备份Backup

Input

输入的第一行包含整数n和k,其中n(2 ≤ n ≤100 000)表示办公楼的数目,k(1≤ k≤n/2)表示可利用的网络电缆的数目。接下来的n行每行仅包含一个整数(0≤ s ≤1000 000 000),表示每个办公楼到大街起点处的距离。这些整数将按照从小到大的顺序依次出现。

Output

输出应由一个正整数组成,给出将2K个相异的办公楼连成k对所需的网络电缆的最小总长度。

Sample Input

5 2
1
3
4
6
12

Sample Output

4

HINT

上面的样例输入给出了前面描述的示例情形

对于每一个测试点,如果写到输出文件中的答案正确,则得到该测试点100%的分数,否则得零分。30%的输入数据满足n≤20。60%的输入数据满足n≤10000。

 

贴个题解。

http://hi.baidu.com/cao_ximeng/blog/item/00f3d81c0c66071134fa415b.html

 

由于我的蒟蒻。。这道题的调试都用在调堆上了。。。一开始怎么也想不到是映射堆写跪了。。。

在对维护中,一个很重要的步骤被我给忽略了。。在删除堆顶的元素的时候,只要把最后一个元素swap上来再向下推。

但是!!!对于堆中元素的更新就必须考虑往上走的情况了!!

因为堆中的每个元素如果不是在最底层,会有相应的两个儿子,这两个儿子是没有直接关系的。对于堆有初步了解的人都知道堆顶元素的左子树可以全部小于(或大于)右子树。

那么在删除堆中的元素的时候,swap上来的最后一个元素有可能是仅比堆顶小一点的值。。。

那么就要先往上走了。。。

还有一点。如果删除的刚好就是最后一个元素。直接删之。。。我蒟蒻地没判断。。。让空单元到堆里面乱窜。。。

 

太讽刺了。。。竟然还要恶补堆的基本操作。。。我该是有多弱啊。。。

 

ACCODE

 

program bzoj_1150;
var heap,pi,l,r:array[0..101000] of longint;
   d:array[0..101000] of int64;
   n,k,tot:longint;
//======================================================
procedure swap(x,y:longint);
var tt:longint;
begin
  pi[heap[x]]:=y; pi[heap[y]]:=x;
  tt:=heap[x]; heap[x]:=heap[y];heap[y]:=tt;
end;
//======================================================
procedure ins(x:longint);
begin
  inc(tot); heap[tot]:=x; pi[x]:=tot;
  x:=tot;
  while x>1 do
    ifd[heap[x]]<d[heap[x shr 1]] then
    begin
     swap(x,x shr 1);
     x:=x shr 1;
    end elsebreak;
end;
//======================================================
procedure del(x:longint);
var g,h,i:longint;
begin
  swap(x,tot);
  pi[heap[tot]]:=0; heap[tot]:=0;
  dec(tot);
  if x>tot then exit;
  while x>1 do
    ifd[heap[x]]<d[heap[x shr 1]] then
    begin
     swap(x,x shr 1);
     x:=x shr 1;
    end elsebreak;
  i:=x;
  while i<tot do
  begin
    g:=i shl 1;h:=i shl 1+1;
    if(g<=tot) and (d[heap[g]]<d[heap[i]])then
    begin
     if (h<=tot) and(d[heap[h]]<d[heap[g]]) then
     begin
       swap(i,h);
       i:=h;
     end else
     begin
       swap(i,g);
       i:=g;
     end;
    endelse
    if(h<=tot) and (d[heap[h]]<d[heap[i]])then
    begin
     swap(i,h);
     i:=h;
    end elsebreak;
  end;
end;
//======================================================
procedure init;
var i:longint;
   pre,now:int64;
begin
  readln(n,k); readln(pre);
  for i:=2 to n do
  begin
    readln(now);d[i]:=now-pre;
    l[i]:=i-1;r[i]:=i+1;
    ins(i);pre:=now;
  end;
  d[1]:=maxlongint; d[n+1]:=maxlongint;
  r[1]:=1; l[n+1]:=n; r[0]:=1; l[n+2]:=n+1;
  ins(1); ins(n+1);
end;
//======================================================
procedure main;
var now,i,tmp:longint;
   ans:int64;
begin
  ans:=0;
  for i:=1 to k-1 do
  begin
   ans:=ans+d[heap[1]];
   now:=heap[1]; del(1);
   del(pi[l[now]]); del(pi[r[now]]);
   d[now]:=d[r[now]]+d[l[now]]-d[now];
   r[l[l[now]]]:=now; l[r[r[now]]]:=now;
   l[now]:=l[l[now]]; r[now]:=r[r[now]];
   ins(now);
  end; ans:=ans+d[heap[1]]; writeln(ans);
end;
//======================================================
begin
  assign(input,'1.in'); reset(input);
  init;
  main;
end.

0 0
原创粉丝点击