好吧,我一开始说这是个神级数据结构毒瘤题,后来改成神题了。

主要是贪心做法的巧妙转化:

首先发现选择的一对必须相邻,于是我们搞出差分。

然后考虑选取最小值时,最小值两侧的数要么同时选,要么都不选。

然后考虑把这三个数合起来变成sum[l] + sum[r] - sum[mid]

这样递归下去即可。

仔细思考,实在是巧妙至极啊!!!


关于代码实现:书上说要在堆和链表上建立映射关系,我觉得十分的毒瘤,打了135行结果五彩斑斓......

然后我决定放弃,不调了,采用神奇的:延迟删除法!就是取堆顶的时候判断。

堆优dijkstra就是这样做的。然后就A了....A了??!!Ahhh

实在是...惨不忍睹。

我TM之前在干嘛。

 #include <cstdio>
#include <queue>
typedef long long LL;
const int N = ; struct HeapNode {
LL val;
int p;
bool operator < (const HeapNode &x) const {
return val > x.val;
}
}; std::priority_queue<HeapNode> Q; struct ListNode {
LL val;
int pre, nex;
bool del;
}li[N]; int head, tail, top; void ListInit() {
head = N - ;
tail = N - ;
li[head].nex = tail;
li[tail].pre = head;
return;
} void insert(LL x) {
HeapNode hd;
hd.val = x;
hd.p = ++top;
Q.push(hd);
int r = tail;
int l = li[r].pre;
li[top].val = x;
li[l].nex = li[r].pre = top;
li[top].pre = l;
li[top].nex = r;
return;
} LL solve() {
HeapNode hd = Q.top();
Q.pop();
int pos = hd.p;
while(li[pos].del || li[pos].val != hd.val) {
hd = Q.top();
Q.pop();
pos = hd.p;
}
int l = li[pos].pre;
int r = li[pos].nex;
int l2 = li[l].pre;
int r2 = li[r].nex;
LL ans = hd.val;
if(l == head && r == tail) {
;
}
else if(l == head) {/// l pos r r2
li[pos].del = li[r].del = ;
li[l].nex = r2;
li[r2].pre = l;
}
else if(r == tail) {/// l2 l pos r
li[pos].del = li[l].del = ;
li[r].pre = l2;
li[l2].nex = r;
}
else{ /// l2 l pos r r2
li[l].del = li[r].del = ;
li[pos].val = li[l].val + li[r].val - ans;
li[l2].nex = li[r2].pre = pos;
li[pos].pre = l2;
li[pos].nex = r2;
hd.val = li[pos].val;
Q.push(hd);
}
return ans;
} int main() {
int k, n;
LL x, tx;
scanf("%d%d", &n, &k);
scanf("%lld", &tx);
for(int i = ; i <= n; i++) {
scanf("%lld", &x);
insert(x - tx);
tx = x;
}
LL ans = ;
for(int i = ; i <= k; i++) {
LL temp = solve();
//printf("%lld \n", temp);
ans += temp;
}
printf("%lld", ans);
return ;
}

AC代码

 #include <cstdio>
#include <algorithm>
using std::swap;
typedef long long LL;
const int N = ; struct ListHeap {
struct HeapNode {
LL val;
int p;
bool operator < (const HeapNode &x) {
return val < x.val;
}
}h[N];
struct ListNode {
LL val;
int pre, nex, p;
}li[N];
int head, tail, top; ListHeap() {
head = N - ;
tail = N - ;
top = ;
li[head].nex = tail;
li[tail].pre = head;
}
inline void up(int x) {
int s = x >> ;
while(x != && h[x] < h[s]) {
swap(h[x], h[s]);
li[h[x].p].p = x;
li[h[s].p].p = s;
x = s;
s = x << ;
}
return;
}
inline void down(int x) {
int s = x << ;
while(s <= top) {
if(s < top && h[s | ] < h[s]) {
s = s | ;
}
if(h[s] < h[x]) {
swap(h[x], h[s]);
li[h[x].p].p = x;
li[h[s].p].p = s;
x = s;
s = x << ;
}
else break;
}
return;
}
inline void del(int x) {
swap(h[x], h[top]);
top--;
li[h[x].p].p = x;
up(x);
down(x);
return;
}
inline void insert(LL x) {
int r = tail, l = li[tail].pre;
int mid = ++top;
li[mid].pre = l;
li[mid].nex = r;
li[l].nex = li[r].pre = mid;
li[mid].val = x;
li[mid].p = top;
h[top].val = x;
h[top].p = mid;
up(top);
return;
}
inline LL solve() {
int mid = h[].p;
int l = li[mid].pre;
int r = li[mid].nex;
if(l == head && r == tail) {
return h[].val;
}
else if(l == head) {
del();
del(li[r].p);
r = li[r].nex;
li[l].nex = r;
li[r].pre = l;
return li[mid].val;
}
else if(r == tail) {
del();
del(li[l].p);
l = li[l].pre;
li[r].pre = l;
li[l].nex = r;
return li[mid].val;
}
else {
del(li[l].p);
del(li[r].p);
LL ans = li[mid].val;
li[mid].val = li[l].val + li[r].val - ans;
l = li[l].pre;
r = li[r].nex;
li[l].nex = li[r].pre = mid;
li[mid].pre = l;
li[mid].nex = r;
h[li[mid].p].val = li[mid].val;
up(li[mid].p);
down(li[mid].p);
return ans;
}
}
}LH; int main() {
int n, k;
LL x, tx;
scanf("%d%d%lld", &n, &k, &tx);
for(int i = ; i <= n; i++) {
scanf("%lld", &x);
LH.insert(x - tx);
tx = x;
}
LL ans = ;
for(int i = ; i <= k; i++) {
ans += LH.solve();
}
printf("%lld", ans);
return ;
}

剧毒万紫千红结构体

洛谷P3620 数据备份的更多相关文章

  1. 洛谷 [P3620] 数据备份

    贪心神题 首先我们发现一个显然的贪心策略,连接相邻两个写字楼总是更优. 所以本题就变成了数轴上一堆点,要选 k 个彼此不相邻的区间,使得区间长度最小 对于 10000 的数据来说,我们可以用 DP 解 ...

  2. 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)

    洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...

  3. 洛谷 P3620 [APIO/CTSC 2007]数据备份 解题报告

    P3620 [APIO/CTSC 2007]数据备份 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同 ...

  4. 洛谷P3620 [APIO/CTSC 2007] 数据备份 [堆,贪心,差分]

    题目传送门 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽 ...

  5. 洛谷P3620 [APIO/CTSC 2007] 数据备份

    题目 贪心+堆. 一般贪心题用到堆的时候都会存在一种反悔操作,因此这个题也不例外. 首先电缆一定是连接两个相邻的点的,这很好证明,其次一个点只能被一条电缆连接,所以我们通过选这个电缆,不选相邻电缆和选 ...

  6. 洛谷$P3620\ [APIO/CTSC 2007]$数据备份 贪心

    正解:贪心 解题报告: 传送门$QwQ$ $umm$感觉这种问题还蛮经典的,,,就选了某个就不能选另一个这样儿,就可以用堆模拟反悔操作 举个$eg$,如果提出了$a_i$,那就$a_{i-1}$和$a ...

  7. Solution -「APIO/CTSC 2007」「洛谷 P3620」数据备份

    \(\mathcal{Description}\)   Link.   给定升序序列 \(\{x_n\}\) 以及整数 \(k\),在 \(\{x_n\}\) 中选出恰 \(k\) 对 \((x_i, ...

  8. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  9. 【洛谷1607】【USACO09FEB】庙会班车

    题面 题目描述 逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼--如果要逛完一整天的集市,他们一定会筋疲力尽的.所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市 ...

随机推荐

  1. 120. 单词接龙 (BFS)

    描述 给出两个单词(start和end)和一个字典,找到从start到end的最短转换序列 比如: 每次只能改变一个字母. 变换过程中的中间单词必须在字典中出现. 如果没有转换序列则返回0. 所有单词 ...

  2. Sigma Function

    做完这道题,我明白了人生的一个巨大道理,那就是: 其他题研究两下,做出来几百行.数论码字前研究半天,做出来十几二十行.做完特别没有成就感... 首先说下这题题意:首先,定义一个函数f[n],即为他所有 ...

  3. Failed to bind properties under 'spring.datasource' to javax.sql.DataSource

    这是我的配置文件 # 国际化配置文件(包名.基础名) spring.messages.basename=i18n.login server.tomcat.uri-encoding=UTF- sprin ...

  4. linux ps命令用法

    -A    列出所有的进程-w    显示加宽可以显示较多的资讯-au    显示较详细的资讯-aux    显示所有包含其他使用者的行程 -A 显示所有进程(等价于-e)(utility)-a 显示 ...

  5. Prism框架中加载类库中时其中第三方类dll提示无法加载程序集

    Prism框架是采用一种依赖注入的方式动态加载程序集,能够在程序需要加载的时候将程序集注入到里面去,实现程序的热插拔效果,而且采用这种框架能够让我们进行一个大项目的独立开发,在最近的一个项目中在独立开 ...

  6. Codevs1541[USACO]围墙涂色

    离散加差分有点涨姿势啊 对我这种菜鸡而言还是第一次看到啊qwq 题面 大意 :n次,每次覆盖一个区间,求覆盖过m次的节点个数 sol:大概是差分的思想加上离散,就可以解决普通差分无法解决的问题了,比如 ...

  7. 微信小程序——引入背景图片【六】

    前言 之前写了一些小程序的博文只是看文档边看边写,了解下他,这次可是真枪真刀的做了! 框架使用的是美团的mpvue,我也是一边学习,一边写的,如有错误之处,还望大家指出. 在这里我有个问题,为什么微信 ...

  8. P1164 小A点菜

    原题链接 https://www.luogu.org/problemnew/show/P1164 此题是一道简单的动规问题 才学两天不是很熟练,我苦思冥想看着题解终于想出来了. 主要的思路如下: 我们 ...

  9. mac centos linux 安装PHP扩展 INTL(国际化) ———— error: 'ext/standard/php_smart_str.h'

    PHP简单源码安装扩展 五个步骤: 详细说明下: cd /fujieace/php7.0/ext/intl:#进入INTL扩展目录? 在编译扩展时候需要phpize准备环境,准备程序需要获取这个目录的 ...

  10. MT【311】三角递推数列

    已知数列$\{a_n\}$满足$a_1=\dfrac{1}{2},a_{n+1}=\sin\left(\dfrac{\pi}{2}a_n\right),S_n$ 为$\{a_n\}$的前$n$项和,求 ...