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

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

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

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

然后考虑把这三个数合起来变成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. Executor介绍

    1.Executor介绍: Executor是mybatis的核心接口之一,其中定义了数据库操作的基本方法,它的子类结构图如下:这这张关系图中,涉及到了模板方法模式和装饰器模式.BaseExecuto ...

  2. Day2 列表,元组,字典,集合

    一,列表 定义:[]内以逗号分隔,按照索引,存放各种数据类型,每个位置代表一个元素. list=['alex', 'jack', 'chen', 'shaoye'] #创建一个列表. 特性: 1.可存 ...

  3. js发布订阅模式实现

    //可以用于无相关页面或组件的事件.数据传递,减少在onShow中的业务,降低代码耦合 let events = {} /**订阅**/ function on(name, self, callbac ...

  4. hive JDBC客户端启动

    JDBC客户端操作步骤

  5. python中random模块

    random与numpy.random对比: 1.random.random():生成[0,1)之间的随机浮点数: numpy.random.random():生成[0,1)之间的随机浮点数: num ...

  6. 在linux系统中实现各项监控的关键技术(2)--内核态与用户态进程之间的通信netlink

    Netlink 是一种在内核与用户应用间进行双向数据传输的非常好的方式,用户态应用使用标准的 socket API 就可以使用 netlink 提供的强大功能,内核态需要使用专门的内核 API 来使用 ...

  7. Linux在shell中进入python敲方向键出现「^[[C^[[D」的解决办法

    安装yum -y install readline-devel,然后在重新编译python

  8. ASP.NET Core Building chat room using WebSocket

    Creating “Login form” We use here simple form where user can insert his or her preferred nick name f ...

  9. WMS工作原理

    图1:创建窗口 图2:通信过程 我们知道其实任何一个窗口的创建,最终都是会创建一个 ViewRootImpl对象.ViewRootImpl 是一很重要的类,类似 ActivityThread 负责跟A ...

  10. qt 在窗口上画框

    在窗口w上面画个黄色的框:在窗口上添加一个label,然后在label上画框 QLabel label(&w); label.setScaledContents(true); QPixmap ...