【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)
Description
给定一颗 \(n\) 个点的树,带边权。
你可以选出一个包含 \(1\) 顶点的连通块,连通块的权值为连接块内这些点的边权和。
求一种选法,使得这个选法的权值是所有选法中第 \(k\) 小的。如果不存在第 \(k\) 小的那输出最大的。
答案对 \(998244353\) 取模。
Hint
- \(1\le n,k\le 10^5\)
- \(\text{边权} \in (0, 10^9]\)
Solution
考虑一个现有的选法,我们考虑如何得到一个新的 尽量小的更大的 选法。
- 将连通块边缘的一条边换下,用另一条与边缘边相邻的边替换。需要在保证新边的边权不小于旧的情况下,新边权最小。
- 在边缘新加入一条最小的边。
我们从初始的选法(只有顶点 \(1\))开始,不断按上述策略拓展出新的选法。如果我们每次 优先拓展权值小的,那么在第 \(k\) 次拓展时我们就得到了答案。
那么现在的问题就是每次拓展如何选边。
我们考虑用一个 堆结构 将每个点所有可以拓展出去的边维护起来。
我们将选法视作一个个状态,每个状态都有一个堆维护 所有待拓展的边缘边。
那么上述两种策略可以转化为:
- 删去堆顶,然后换上新的堆顶。很显然就得到了一个次小选法。
- 选择堆顶对应边另一端的点,表示新拓展的顶点。将该顶点对应出边的边集 合并 到当前堆上。
这里设计到了堆的合并,又不得覆盖原来的信息,那么首选 可持久化左偏树 了。
最后复杂度 \(O((n+k)\log n + k\log k)\)。空间 \(O((n+k)\log n)\)。
Code
/*
* Author : _Wallace_
* Source : https://www.cnblogs.com/-Wallace-/
* Problem : CH 弱省互测 Round #1 OVOO
*/
#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N = 1e5 + 5;
const int mod = 998244353;
int n, k;
int f[N], v[N];
struct Edge {
int to, nxt;
int len;
} e[N];
int head[N], ecnt = 0;
inline void insert(int u, int v, int w) {
e[ecnt] = Edge{v, head[u], w};
head[u] = ecnt++;
}
namespace LefT {
struct lef {
int ch[2], dist;
int end, val;
} tr[N << 5];
int total = 0;
inline int create(int v, int e) {
int x = ++total;
tr[x] = lef{{0, 0}, 1, e, v};
return x;
}
inline int copy(int x) {
return tr[++total] = tr[x], total;
}
int merge(int x, int y) {
if (!x || !y) return x | y;
if (tr[x].val > tr[y].val) swap(x, y);
int z = copy(x);
tr[z].ch[1] = merge(tr[x].ch[1], y);
if (tr[tr[z].ch[0]].dist < tr[tr[z].ch[1]].dist)
swap(tr[z].ch[0], tr[z].ch[1]);
tr[z].dist = tr[tr[z].ch[1]].dist + 1;
return z;
}
};
int root[N];
void prework(int x) {
using namespace LefT;
for (int i = head[x]; ~i; i = e[i].nxt) {
int y = e[i].to, l = e[i].len;
root[x] = merge(root[x], create(l, y));
prework(y);
}
}
struct statu {
int x; long long v;
inline bool operator < (const statu& rhs) const {
return v > rhs.v;
}
}; priority_queue<statu> pq;
signed main() {
ios::sync_with_stdio(false);
memset(head, -1, sizeof(head));
cin >> n >> k;
for (int i = 2; i <= n; i++) {
cin >> f[i] >> v[i];
insert(f[i], i, v[i]);
}
prework(1);
using namespace LefT;
long long ans = 0ll;
pq.push(statu{root[1], tr[root[1]].val});
for (--k; k && !pq.empty(); --k) {
int x = pq.top().x;
long long val = pq.top().v;
pq.pop(), ans = val;
int cur = merge(tr[x].ch[0], tr[x].ch[1]);
if (cur) pq.push(statu{cur, val - tr[x].val + tr[cur].val});
cur = merge(cur, root[tr[x].end]);
if (cur) pq.push(statu{cur, val + tr[cur].val});
}
cout << ans % mod << endl;
}
【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)的更多相关文章
- 弱省互测#0 t2
题意 给定两个字符串 A 和 B,求下面四个问题的答案: 1.在 A 的子串中,不是 B 的子串的字符串的数量. 2.在 A 的子串中,不是 B 的子序列的字符串的数量. 3.在 A 的子序列中,不是 ...
- 弱省互测#2 t3
题意 给出\(n\)个01字节和\(m\)个01字节,要求用后者去匹配前者,两个串能匹配当且仅当除了每个字节末位不同,其他位都要相同.问匹配后者至少有多少个末位不同.(\(1 \le m \le n ...
- 弱省互测#2 t2
题意 给两个树,大小分别为n和m,现在两棵树各选一些点(包括1),使得这棵树以1号点为根同构(同构就是每个点的孩子数目相同),求最大的同构树.(n, m<=500) 分析 我们从两棵树中各取出一 ...
- 弱省互测#1 t3
题意 给出一棵n个点的树,求包含1号点的第k小的连通块权值和.(\(n<=10^5\)) 分析 k小一般考虑堆... 题解 堆中关键字为\(s(x)+min(a)\),其中\(s(x)\)表示\ ...
- 弱省互测#0 t3
Case 1 题意 要求给出下面代码的答案然后构造输入. 给一个图, n 个点 m 条边 q 次询问,输出所有点对之间最大权值最小的路径. 题解 把每一个询问的输出看成一条边,建一棵最小生成树. Ca ...
- 弱省互测#0 t1
题意 给一个\(N \times M\)的01网格,1不能走,从起点\((1, 1)\)走到\((N, M)\),每次只能向下或向右走一格,问两条不相交的路径的方案数.(n, m<=1000) ...
- 【loj2461】【2018集训队互测Day 1】完美的队列
#2461. 「2018 集训队互测 Day 1」完美的队列 传送门: https://loj.ac/problem/2461 题解: 直接做可能一次操作加入队列同时会弹出很多数字,无法维护:一个操作 ...
- luoguP3769 [CH弱省胡策R2]TATT
luoguP3769 [CH弱省胡策R2]TATT PS:做这题前先切掉 P4148简单题,对于本人这样的juruo更助于理解,当然dalao就当练练手吧 题目大意: 现在有n个四维空间中的点,请求出 ...
- 【2018集训队互测】【XSY3372】取石子
题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...
随机推荐
- 【java从入门到精通】day10-Java流程控制2-switch多选择结构
1.switch多选择结构 switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支. switch语句中的变量类型可以是: byte.short.int或者char 从j ...
- Freebsd10.2安装包升级pkg引起环境破坏的解决
前言 freebsd10.2环境在安装一个新软件包的时候提示升级pkg到1.10.1,然后点击了升级,然后整个pkg环境就无法使用了 记录 升级完了软件包以后第一个错误提示 FreeBSD: /usr ...
- 【芯片手册开发】Sil9136音频开发详细分析+源码实战
目录 前言 参考 手册使用+实战 配置 Configuring Audio Using I2S 总结实现 前言 默认在开发了视频方面后 这方面的工作本来可以找技术支持拿个例程参考下,很快就可以的写出来 ...
- CSS 背景常用属性
CSS 背景常用属性 background-color 这个属性过于简单, 以下写法均可 background-color:red; background-color:rgb(0,0,255); ba ...
- Mysql binlog备份数据及恢复数据,学会这个,我在也不怕删库跑路啦~
导读 我一直都主张,技多不压身(没有学不会的技术,只有不学习的人),多学一项技能,未来就少求人一次.网上经常听到xxx删库跑路,万一真的遇到了,相信通过今天的学习,也能将数据再恢复回来~~~ 当然啦, ...
- 【JAVA基础】数组练习案例一
/* * * 输入5个学生成绩 * 计算出每个成绩与最高分的差距 * 根据差距分配等级 * * */ import java.util.Scanner; public class ArrayTask ...
- CDR魔镜插件是什么,有哪些功能?
CDR魔镜插件是一款功能强大的CorelDRAW插件,很多CDR用户很早直接就有接触,因其强大的功能性和快速运行的特点被广大用户所喜爱,没有繁琐的选项,无论新人小白,还是制图高手都能够很快的适应,实现 ...
- CorelDRAW“出血线”的精准预设与辅助线便捷操作
CorelDRAW软件是一款常用的制图工具,非常适合用于印刷品输出,各种印刷图文制作都依赖于它.所以,我们设计者每次用CorelDRAW制图的一个关键就是要做好"标尺辅助线"设置, ...
- layer 父弹窗获取子弹窗内的dom节点元素和变量
1 var body = layer.getChildFrame('body', index); //获取子弹窗的dom节点 2 3 var iframeWin = window[layero.fin ...
- matlab中实现 IEEE754浮点数 与 一般十进制数之间 互相转换的方法
------------恢复内容开始------------ %2020/12/2 11:42:31clcformat long % IEEE754 to deca = '40800000'a = d ...