【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! 显然不会无解…… 为了方便计算石子个数,在 ...
随机推荐
- leetcode bitmap系列问题整理
1. 题目: 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量). 示例 : 输入: 11输出: 3解释: 整数 11 的二进制表示为 000000 ...
- python之《matplotlib》
# _*_coding:utf-8_*_# /usr/bin/env python3# Author:book Mikiimport matplotlib.pyplot as pltimport nu ...
- asyncio多进程+pyppeteer浏览器控制+pyquery解析实现爬虫demo
import asyncio from pyppeteer import launch from pyquery import PyQuery as pq async def main(): brow ...
- Java面试那些事
网址链接:https://mp.weixin.qq.com/s/BkiDwyjua4iwws7gWHwK9Q 引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试 ...
- [原题复现+审计][CISCN2019 华北赛区 Day1 Web2]ikun(逻辑漏洞、JWT伪造、python序列化)
简介 原题复现: 考察知识点:逻辑漏洞.JWT伪造.python反序列化 线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台 ...
- Docker学习第二天(Docker容器管理)
简介 emmmm Docker 容器管理 推荐文章:容器技术概述 run里面的子选项 1.使用run命令创建容器 docker container run -it ubuntu /bin/bash / ...
- 如何用MathType 7输入x的一阶导数
物理学.几何学.经济学等学科中的一些重要概念都可以用导数来表示.如,导数可以表示运动物体的瞬时速度和加速度.可以表示曲线在一点的斜率.还可以表示经济学中的边际和弹性.那么作为专业的公式编辑器,如何输入 ...
- SD卡被格式化了还能恢复吗
SD卡轻便小巧,它的主要功能是拓展便携式设备.包括:数据相机.手机及其他的多媒体播放器等的存储空间,缓解设备本身的存储压力. 很多用户反应,SD卡使用了一定的时间后,会出现SD卡受损的提示,再次打开的 ...
- Mac book系统的垃圾清理如何进行?
当我们看到电脑发出的内存不足的提示,这就意味着: 1.Mac系统的内存即将被占满 2.电脑将运行缓慢 3.开机速度变慢 很多人使用Mac book一年以后都会发现,它的运行开始逐渐变慢,爱电脑的人在将 ...
- Cypress系列(93)- Cypress.dom 命令详解
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 作用 与 DOM 元素相关的 helpe ...