E - Subtree K-th Max

  • 题意:给定一个以 \(1\) 为根的树,节点个数为 \(n(\le 1e5)\),每个点都有自己的点权。需要回答 \(m(\le1e5)\) 次询问。每次询问给出两个数字 \(V,K\),输出节点 \(V\) 的子树中第 \(K(\le20)\) 大的值。保证询问中的子树节点个数大于 \(K\)。

  • 观察数据范围发现 \(K\) 最大为 20,所以 DFS 统计子树中前20大的值即可

    参考文章:浅谈 DFS 序

  • 拓展:如果没有 \(K\le20\) 的话就得考虑 DFS + 主席树来做了

PS: 子树问题可以用DFS转换成序列上的问题

AC Code

int n, q;
void solve() {
cin >> n >> q;
vector<vector<int>> X(n + 1, vector<int>(20));
for (int i = 1; i <= n; i += 1) cin >> X[i][0];
vector<vector<int>> G(n + 1);
for (int i = 1, a, b; i < n; i += 1) {
cin >> a >> b;
G[a].push_back(b);
G[b].push_back(a);
}
vector<int> tmp(40);
function<void(int, int)> DFS = [&](int u, int par) {
for (int v : G[u]) if (v != par) {
DFS(v, u);
merge(X[u].begin(), X[u].end(), X[v].begin(), X[v].end(), tmp.begin(), greater<int>());
for (int i = 0; i < 20; i += 1) X[u][i] = tmp[i];
}
};
DFS(1, 0);
for (int i = 0, V, K; i < q; i += 1) {
cin >> V >> K;
cout << X[V][K - 1] << "\n";
}
}

F - Construct Highway

  • 题意:有 \(n(≤1e5)\)个点,你需要构造出一颗数,满足每个点的度数都为 \(d[i]\)(\(d[i]\) 为题目给定的)。并目题目 已经给了 \(m(m<n-1)\) 条边。

思路参考 (知乎—严格鸽

考虑一下贪心,我们先找到一个度数剩余为1的点 \(u\) ,再去找到一个度数剩余大于等于 \(2\) 的点 \(v\) ,满足两点之间是不联通的。那我们就连一条边给 \((u,v)\).

但是怎么做呢?

我们可以按照题目给定的边来构造联通块,对于 \((u,v)\) 我们保证两个点来自不同的连通块。

以下度数为剩余的度数

所以我们需要维护联通块总的度数,并将联通块分为度数等于 \(1\),和度数大于等于 \(2\) 两种。前者为\(C1\),后者为 \(C2\) 通过枚举 \(C2\) 中的联通块 \(vec\) ,将 \(vec\) 中的点与 \(C1\) 中的点连边,注意,最后 \(vec\) 中应该剩下一个点,而这个点就可以代表整个联通块 \(vec\) ,其度数为 \(1\) ,我们将其加入到 \(C1\) 中。

可以得到,\(vec\) 与 \(C1\) 中的点一定是不连通的。

这样的我们就可以构造出一颗树了,当然需要一些特判,具体我写到代码的注释里了。

int d[MAXN];
vector<int>g[MAXN];
int n, m, u, v;
void slove() {
cin >> n >> m;
int sum = 0;
for (int i = 1; i <= n; i++) { cin >> d[i]; sum += d[i]; }
if (sum != 2 * (n - 1))NO;//树的总度数为2*(n - 1)
UF uf = UF(n);
while (m--) {
cin >> u >> v;
d[u]--, d[v]--;
uf.Union(u, v);
if (d[u] < 0 || d[v] < 0)NO;//度数不能小于0
}
//处理联通块
for (int u = 1; u <= n; u++) {
while (d[u]--) {
//这里我们这样可以方便的搞出联通块的最后一个点
g[uf.findFather(u)].push_back(u);
}
}
//度数为1 度数为2
vector<int>c1; vector<vector<int>>c2;
for (int u = 1; u <= n; u++) {
if (g[u].size()) {
if (g[u].size() == 1)c1.push_back(g[u][0]);
else c2.push_back(g[u]);
}
}
vector<pair<int, int>>ans;
for (auto &vec : c2) {
int last = vec.back(); vec.pop_back();//剩下一个点
for (int u : vec) {
if (c1.size() == 0)NO;//如果c1没有了
int v = c1.back(); c1.pop_back();
ans.push_back({ u,v });
uf.Union(u, v);
}
c1.push_back(last);
}
//最后c1还是被push了,所以最后c1的个数一定要为2,如果个数大于2的话,不可能联通
if (c1.size() != 2)NO;
u = c1[0], v = c1[1];
ans.push_back({ u,v });
uf.Union(u, v);
if (uf.count == 1)
for (auto x : ans)cout << x.first << " " << x.second << endl;
else NO;
}

Denso Create Programming Contest 2022(AtCoder Beginner Contest 239) E~F 题的更多相关文章

  1. M-SOLUTIONS Programming Contest 2021(AtCoder Beginner Contest 232) 题解

    目录 G - Modulo Shortest Path H - King's Tour 因为偷懒就只写G和H的题解了. G - Modulo Shortest Path 首先可以观察到对于一条从点\( ...

  2. atcoder beginner contest 251(D-E)

    Tasks - Panasonic Programming Contest 2022(AtCoder Beginner Contest 251)\ D - At Most 3 (Contestant ...

  3. AtCoder Beginner Contest 076

    A - Rating Goal Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Takaha ...

  4. AtCoder Beginner Contest 100 2018/06/16

    A - Happy Birthday! Time limit : 2sec / Memory limit : 1000MB Score: 100 points Problem Statement E8 ...

  5. KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解

    KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...

  6. AtCoder Beginner Contest 255(E-F)

    Aising Programming Contest 2022(AtCoder Beginner Contest 255) - AtCoder E - Lucky Numbers 题意: 给两个数组a ...

  7. AtCoder Beginner Contest 184 题解

    AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...

  8. AtCoder Beginner Contest 052

    没看到Beginner,然后就做啊做,发现A,B太简单了...然后想想做完算了..没想到C卡了一下,然后还是做出来了.D的话瞎想了一下,然后感觉也没问题.假装all kill.2333 AtCoder ...

  9. AtCoder Beginner Contest 053 ABCD题

    A - ABC/ARC Time limit : 2sec / Memory limit : 256MB Score : 100 points Problem Statement Smeke has ...

  10. AtCoder Beginner Contest 136

    AtCoder Beginner Contest 136 题目链接 A - +-x 直接取\(max\)即可. Code #include <bits/stdc++.h> using na ...

随机推荐

  1. 如何判断lib和dll是32位还是64位?答案是使用微软的dumpbin工具,后面讲了如何使用gcc生成lib和dll

    为什么我会考虑这个问题呢?因为我在使用java去调用一个c的lib库的时候,弹出以下警告: D:\work\ideaworkpaces\jdk21Test001\src\main\java\lib\h ...

  2. GZY.Quartz.MUI(基于Quartz的UI可视化操作组件) 2.6.0发布 兼容.Net8.0

    前言 为了迎接.Net8.0 2.6.0终于发布了~ 更新内容: 兼容.NET8.0 新增界面按分组名称排序功能 优化本地持久化时文件路径异常的问题 优化数据库持久化时偶现的异常问题 新增简易授权,增 ...

  3. Git日志的相关操作

    显示日志 最单纯的日志命令 git log 单条显示 git log -条数 # 例如 git log -2 显示两条 提交信息单行输出 git log --oneline 日志图表显示 git lo ...

  4. @Async实现异步任务

    1.@Async是SpringBoot自带的一个执行步任务注解 @EnableAsync // 开启异步 @SpringBootApplication public class Application ...

  5. 如何基于 k8s做私有化部署

    公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. 随着国内数字化转型的加速和国产化进程推动,软件系统的私有化部署已经成为非常热门的话题,因为私有化部署赋予了企业更大的灵活和 ...

  6. 【笔记整理】[案例]使用正则表达式来提取36Kr新闻

    import datetime import json import re import requests class Kr36(object): def __init__(self): self.u ...

  7. 数字孪生系统为何需要将GIS系统进行融合?

    数字孪生是一种通过数字模型实时仿真现实世界的技术,而GIS(地理信息系统)则是用于收集.存储.处理和展示地理数据的工具.将数字孪生系统与GIS系统进行融合,可以为各行业带来诸多优势和创新.那么数字孪生 ...

  8. MyBatis 批量更新的处理

    一般来讲,在使用 MyBatis 进行数据库的访问时,通常会遇到需要更新数据的相关业务,在某些业务场景下,如果需要进行一批次的数据更新,可能性能不是特别理想.本文将简要介绍几种能够高效地处理批量更新数 ...

  9. MySQL 基础(四)锁

    解决并发事务带来的问题 写-写情况 任意一种事务隔离级别都不允许 "脏写" 的发生,因为这样会使得数据混乱.所以,当多个未提交的事务相继对一条记录进行改动时,就需要使得这些事务串行 ...

  10. 3大方面升级华为云CCE集群体验,助力集群高效运维管理

    本文分享自华为云社区<华为云从心打造CCE集群升级体验,助力集群高效运维管理>,作者:云容器大未来 . 在云原生时代浪潮的推动下,Kubernetes的发展日新月异,更新的集群版本可以带来 ...