bzoj 1150 [CTSC2007]数据备份Back…

来源:互联网 发布:移动进销存软件 编辑:程序博客网 时间:2024/05/20 22:03

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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 昆山社保号是8位怎么办 高铁票误了时间怎么办 动车票没赶上车怎么办 铁路用户名已存在要怎么办 铁路12306用户名忘了怎么办 铁路12306的用户名忘了怎么办 铁路12306注册名已存在怎么办 12306账号密码忘记了怎么办 12306登录名忘记了怎么办 电脑系统崩溃开不了机怎么办 高铁车票没赶上怎么办 机票错点了退票怎么办 快递号码留错了怎么办 物流号码留错了怎么办 12306身份信息被注册怎么办 12306注册身份信息重复怎么办 12306账号被注册了怎么办 高铁账号忘记了怎么办 铁路12306网站密码错误怎么办 网上买火车票密码忘了怎么办 快递没收到点了确认收货怎么办 快递没收到自动确认收货怎么办 房地产股市汇率一齐暴跌怎么办 尼日利亚落地签过期了怎么办 期货亏光了所有怎么办 期货钱亏完了该怎么办 做黄金亏损500万怎么办 炒黄金被骗35万怎么办 淘宝发货填错单号怎么办 发货单号填错了怎么办 发快递忘了单号怎么办 国际物流查不到物流怎么办 纸币上印邪教该怎么办 钥匙掉到电梯缝里怎么办 汽车电子钥匙铜线折一根怎么办 防盗门的锁不好开怎么办 同学帮刷饭卡说不用还钱了怎么办 em231电源指示灯不亮怎么办 运行广联达卡住怎么办 马桶被粪便(大便)堵了怎么办 子宫壁厚12mm怎么办