首先选取的线段一定是相邻两个端点线段,那么我们贪心的考虑这个问题,我们先在这n-1条线段中选出最短的一条,然后将这条线段的值改为左面的线段的值+右面的线段的值-自己的值,用这条线段取代原来这三条线段,继续做,那么这个取m次出来之后的就是答案,对于证明,我们可以大概的去想,选了新的线段代表不选这条原本的线段,然后选另两条相邻的线段,这样选的线段的条数只是+1,相当于又取了一条线段,正确性的证明可以大概感知。

  至于选最小的用堆来维护就行了,因为需要删除精确到点编号,对堆用的不熟悉,所以用sbt代替。

/**************************************************************
Problem:
User: BLADEVIL
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ //By BLADEVIL
type
pointer=^rec;
rec =record
pred, succ :pointer;
num, fuck :int64;
end;
shit =record
shit1, shit2 :longint;
end; var
n, m :longint;
a :array[..] of pointer;
left, right, size :array[..] of longint;
key, adr :array[..] of longint;
t, tot :longint;
ans :int64; 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]]+;
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]]+;
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:int64);
begin
if t= then
begin
inc(tot);
t:=tot;
left[t]:=;
right[t]:=;
size[t]:=;
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:int64):shit;
var
damn :shit;
begin
dec(size[t]);
if (v=key[t]) and (k=adr[t]) or (v>key[t]) and (right[t]=) or (v<key[t]) and (left[t]=) then
begin
delete.shit1:=key[t];
delete.shit2:=adr[t];
if (left[t]=) or (right[t]=) then
t:=left[t]+right[t] else
begin
damn:=delete(left[t],v+,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 left[t]= then exit(adr[t]) else exit(mini(left[t]));
end; procedure init;
var
i :longint;
null :pointer; begin
read(n,m);
for i:= to n do
begin
new(null);
a[i]:=null;
read(a[i]^.num);
end;
for i:=n downto do a[i]^.num:=a[i]^.num-a[i-]^.num;
a[]^.num:=;
for i:= to n do
begin
if i= then a[i]^.pred:=a[n] else a[i]^.pred:=a[i-];
if i=n then a[i]^.succ:=a[] else a[i]^.succ:=a[i+];
end;
for i:= to n do a[i]^.fuck:=i;
end; procedure main;
var
i :longint;
x :longint;
begin
t:=;
for i:= to n do insert(t,a[i]^.num,i);
for i:= 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.

bzoj 1150 贪心的更多相关文章

  1. [BZOJ 1150] [CTSC2007] 数据备份Backup 【贪心 + 链表】

    题目链接:BZOJ - 1150 题目分析 可以看出,我们选的 k 条边一定是相邻两点之间的线段.我们可以将每条边看成一个点,那么我们就是要在 n-1 个点中选出互不相邻的 k 个,使它们的和最小. ...

  2. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  3. BZOJ 1150 [CTSC2007]数据备份Backup(贪心+优先队列)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1150 [题目大意] 给出n个数,请你挑出k对(每个数不可重复选取),使得他们差的绝对值 ...

  4. bzoj 1150&2151&2288(双向链表+堆)(贪心)

    经典模型:在n个点中选k个点,要求两两不相邻,且总权值最大/最小. 做法:用双向链表串起来,把所有点丢进堆里,选择一个点的时候把它左右两个点从双向链表和堆中去除,然后把这个点的权值加进ans,出堆后改 ...

  5. 【链表】bzoj 1150: [CTSC2007]数据备份Backup

    1150: [CTSC2007]数据备份Backup Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1136  Solved: 458[Submit] ...

  6. 【BZOJ 1150】[CTSC2007]数据备份Backup

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 选择的连接肯定是相邻的点对. 那么我们处理出来长度为n-1的数组a 其中a[i-1] = dis[i]-dis[i-1] 那么问题就 ...

  7. bzoj 1193 贪心

    如果两点的曼哈顿距离在一定范围内时我们直接暴力搜索就可以得到答案,那么开始贪心的跳,判断两点横纵坐标的差值,差值大的方向条2,小的条1,不断做,直到曼哈顿距离较小时可以暴力求解. 备注:开始想的是确定 ...

  8. bzoj 2697 贪心

    就贪心就行了,首先可以看成n个格子,放物品,那么 一个物品假设放3个,放在1,k,n处,那么价值和放在1,n 是一样的,所以一个物品只放两个就行了,价值大的应该尽量放 在两边,那么排序之后模拟就行了 ...

  9. bzoj 3037 贪心

    我们可以贪心的分析,每个点的入度如果是0,那么这个点不可能 被用来更新答案,那么我们每次找入度为0的点,将他去掉,如果他连的 点没有被更新过答案,那么更新答案,去掉该点,环的时候最后处理就行了 /** ...

随机推荐

  1. 获取已安装app的bundle id

    备注:以下是私有api 苹果审核会被拒绝. 导入头文件 #import <objc/runtime.h> /// 获取其他APP信息(iOS11无效) + (NSArray *)getOt ...

  2. [PocketFlow]解决在coco上mAP非常低的bug

    1.问题 继上次训练挂起的bug后,又遇到了现在评估时AP非常低的bug.具体有多低呢?Pelee论文中提到,用128的batchsize大小在coco数据集上训练70K次迭代后,AP@0.5:0.9 ...

  3. 【版本控制】VisualSVN Server更改SVN版本库存放路径的方法

    最近也玩起了SVN软件版本管理,在本机上安装了VisualSVN Server+TortoiseSVN,感觉还不错吧.但是,版本库存在哪里呢?在安装VisualSVN Server时,已经默认设置了, ...

  4. android中常见的命名及其特点详解

    Paseal命名法 Paseal命名法特点:String MyName-DelphiInt MyAge每个单词首字母大写 Camel命名法 Camel(驼峰的意思)命名法特点:String myNam ...

  5. Luogu3959 NOIP2017宝藏(状压dp)

    按层dp,f[i][j]表示已扩展i子集的节点当前在第j层的最小代价,预处理点集间距离即可. #include<iostream> #include<cstdio> #incl ...

  6. BZOJ4416 SHOI2013阶乘字符串(状压dp)

    当n大到一定程度(>21)时一定无解,并不会证. 如果要取出一个排列,显然应该让每一位在序列中的位置尽量靠前.于是设f[S]表示存在S子集中这些字母所组成的所有排列的最短前缀的长度,枚举当前排列 ...

  7. Ubuntu下Eclipse中运行Hadoop程序的参数问题

    需要统一的参数: 当配置好eclipse中hadoop的程序后,几个参数需要统一一下: hadoop安装目录下/etc/core_site.xml中 fs.default.name的端口号一定要与ha ...

  8. null?对象?异常?到底应该如何返回错误信息

    这篇文章记录我的一些思考.在工作了一段时间之后. 问题的核心很简单:到底如何返回错误信息. 学生时代,见到过当时的老师的代码: if (foo() == null) { } 当然,这位老师是一位比较擅 ...

  9. [LG4890]Never·island DP

    ---题面--- 题解: 感到此题非常的神奇...看了大佬的题解才懂的. 首先建模: 先把所有队伍的出去回来时间都放在一个数组里,然后排序,从左到右扫一边,给每个队伍都建一个带权点,进行如下操作: ( ...

  10. BZOJ 1023: [SHOI2008]cactus仙人掌图 | 在仙人掌上跑DP

    题目: 求仙人掌直径 http://www.lydsy.com/JudgeOnline/problem.php?id=1023 题解: 首先给出仙人掌的定义:满足所有的边至多在一个环上的无向联通图 我 ...