洛谷P3620 数据备份
好吧,我一开始说这是个神级数据结构毒瘤题,后来改成神题了。
主要是贪心做法的巧妙转化:
首先发现选择的一对必须相邻,于是我们搞出差分。
然后考虑选取最小值时,最小值两侧的数要么同时选,要么都不选。
然后考虑把这三个数合起来变成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 数据备份的更多相关文章
- 洛谷 [P3620] 数据备份
贪心神题 首先我们发现一个显然的贪心策略,连接相邻两个写字楼总是更优. 所以本题就变成了数轴上一堆点,要选 k 个彼此不相邻的区间,使得区间长度最小 对于 10000 的数据来说,我们可以用 DP 解 ...
- 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)
洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...
- 洛谷 P3620 [APIO/CTSC 2007]数据备份 解题报告
P3620 [APIO/CTSC 2007]数据备份 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同 ...
- 洛谷P3620 [APIO/CTSC 2007] 数据备份 [堆,贪心,差分]
题目传送门 题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽 ...
- 洛谷P3620 [APIO/CTSC 2007] 数据备份
题目 贪心+堆. 一般贪心题用到堆的时候都会存在一种反悔操作,因此这个题也不例外. 首先电缆一定是连接两个相邻的点的,这很好证明,其次一个点只能被一条电缆连接,所以我们通过选这个电缆,不选相邻电缆和选 ...
- 洛谷$P3620\ [APIO/CTSC 2007]$数据备份 贪心
正解:贪心 解题报告: 传送门$QwQ$ $umm$感觉这种问题还蛮经典的,,,就选了某个就不能选另一个这样儿,就可以用堆模拟反悔操作 举个$eg$,如果提出了$a_i$,那就$a_{i-1}$和$a ...
- Solution -「APIO/CTSC 2007」「洛谷 P3620」数据备份
\(\mathcal{Description}\) Link. 给定升序序列 \(\{x_n\}\) 以及整数 \(k\),在 \(\{x_n\}\) 中选出恰 \(k\) 对 \((x_i, ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 【洛谷1607】【USACO09FEB】庙会班车
题面 题目描述 逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼--如果要逛完一整天的集市,他们一定会筋疲力尽的.所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市 ...
随机推荐
- MQ4入门篇(一)
写一个下单功能,和一个平仓功能: 下单: 1:下单使用到的函 int OrderSend(string symbol, int cmd, double volume, double price, in ...
- 判断String类型字符串是否为空的方法
在项目中经常遇到要判断String类型的字段是否为空操作 我们可以用Apache提供的StringUtils这个工具类,不用自己去判断,也不用自己封装判断空的方法 它有两个版本,一个是org.apac ...
- tomcat优化实例
———————————————————————————————————— 一.运行模式优化 修改tomcat运行模式为nio<Connector port="80" prot ...
- FormDestroy 和 FormClose 有什么区别和联系?
1.窗口的所有资源真正释放时调用 FormDestroy.当你关闭窗口时,VCL会调用FormClose,如果你在FormClose里写Action = caFree,那么VCL会继续调用FormDe ...
- Delphi MDI 子窗体的创建和销毁 [zhuan]
1.如果要创建一个mdi child,先看是否有这个child 存在,如果有,则用它,如果没有再创建 //该函数判断MDI 子窗体是否存在,再进行创建和显示function isInclude(for ...
- 1.docker 数据卷的备份和恢复(非大数据量)
在生产环境中使用 Docker,很多时候需要对数据进行持久化,或者进行容器间的数据共享. 容器中的管理数据主要有两种方式: 数据卷 (Data Volumes): 容器内数据直接映射到本地主机环境: ...
- 当考虑到并发问题时候,我们需要将给表插入id的代码挪到service中,目的是将其放到一个事务中,保准事务的一致性
- c++ 实现哈夫曼树中遇见的问题
为了提高效率求得 叶子 节点中权值最小的两个元素,我们需要使用堆数据结构,它可以以O(logn)的复杂度 取得n个元素中的最小元素.为了绕过堆的实现,我们可以使用标准模板库中相应的标准模板—优先队列. ...
- git 强制推送
Git 强制推送方法(一般不建议使用) $ git push -u origin master -f
- Docker自制CentOS镜像
系统环境:CentOS 7.3 将yum源切换到阿里源 可以直接写成一个脚本 #!/bin/sh mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos ...