[AtCoder] NIKKEI Programming Contest 2019

  本来看见这一场的排名的画风比较正常就来补一下题,但是完全没有发现后两题的AC人数远少于我补的上一份AtCoder。


A - Subscribers

  首先始终 \(max = \min(A, B)\) ,\(min\) 的话如果 \(A + B \leq N\) ,那么就是 \(0\) ,否则就是 \(A + B - N\) 。

int n, a, b;

int main() {
read(n), read(a), read(b);
if (a + b <= n) printf("%d 0\n", std::min(a, b));
else printf("%d %d\n", std::min(a, b), a + b - n);
}

B - Touitsu

  直接枚举每一位,看看有几个相同的就行了。

int n, ans;
char a[N], b[N], c[N]; int main() {
scanf("%d%s%s%s", &n, a + 1, b + 1, c + 1);
for (int i = 1; i <= n; ++i) {
if(a[i] == b[i] && b[i] == c[i]) ;
else if(a[i] != b[i] && a[i] != c[i] && b[i] != c[i]) ans += 2;
else ++ans;
}
printf("%d\n", ans);
}

C - Different Strokes

  挺好一道题,就是有点简单。

  我们考虑对于每一个人来说,假设他选的集合是 \(S\) ,他要最大化这个东西:

\[\sum_{i \in S} a[i] - \sum_{i \notin S} b[i]
\]

  如果我们假设 \(B = \sum \limits_{i = 1} ^ n b[i]\) ,那么上式可化为:

\[(\sum_{i \in S} a[i] +b[i]) -B
\]

  因此不管是谁,都应该尽量选择 \(a[i]+b[i]\) 大的位置上的数。直接用一个堆维护一下就可了。(不过好像可以直接排一下序就可以啦,我似乎傻掉了)

const int N = 1e5 + 7;

int n, a[N], b[N];
ll ans; struct cmp {
int operator () (const int &x, const int &y) const {
return a[x] + b[x] < a[y] +b[y];
}
};
std::priority_queue<int, std::vector<int>, cmp> q; int main() {
read(n);
for (int i = 1; i <= n; ++i) read(a[i]), read(b[i]), q.push(i);
for (int i = 1; i <= n; ++i) if (i & 1) ans += a[q.top()], q.pop(); else ans -= b[q.top()], q.pop();
printf("%lld\n", ans);
}

D - Restore the Tree

  怎么感觉 D 比 C 还简单啊。至少 C 还要想一会儿列个式子, 这道题好像是读完题就可以开始写了。

  因为保证新加的边始终是从祖先连向孩子的,所以图里面的边实际上表示了深度的大小关系,因此根肯定还是入度为 0 的。找到根以后拓扑排序一下就可了,最后一个拓扑到 \(i\) 的点就是 \(i\) 的父亲。

const int N = 1e5 + 7;

int n, m, x, y, rt, idg[N], fa[N];

struct Edge {int to, ne;} g[N]; int head[N], tot;
inline void Addedge(int x, int y) {g[++tot].to = y; g[tot].ne = head[x]; head[x] = tot;} int q[N], hd, tl;
inline void BFS() {
q[++tl] = rt;
while (hd < tl) {
int x = q[++hd];
for fec(i, x, y) if (!--idg[y]) fa[y] = x, q[++tl] = y;
}
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
read(n), read(m);
for (int i = 1; i <= n - 1 + m; ++i) read(x), read(y), Addedge(x, y), ++idg[y];
for (int i = 1; i <= n; ++i) if(!idg[i]) rt = i;
BFS();
for (int i = 1; i <= n; ++i) printf("%d\n", fa[i]);
}

E - Weights on Vertices and Edges

  好题啊。

  一开始我想的是肯定要从大到小枚举边要不要删。然后可以发现不在最小生成树上的边不管怎么删都不影响原图的连通性,于是可以直接把原图变成一棵树的时候,那么可以直接上 LCT 来维护连通性以及一些信息。但是似乎方法是成立的,只是额在AtCoder上如果还要写LCT,是真的不敢想啊。

  于是又思考了一个小时,也没什么新思路,只能去看了一下题解。

  是这样的,我们对于删边发过来,变成从小到大加边,用并查集来维护一下每个联通块的点权和。但是我们会发现,有些边可能之前是不能加的,但是随着后续的加边,联通块扩大了,那些边就可以加入了!

  题解提供了一种很巧妙的办法,我们对于那样的边,我们把它们的联通块先连起来,但是并查集要记录所有并没有真正加进去的边的数量,显然后面如果我们真正加边的时候,就可以把该联通块并完以后,里面没有加的边都加进去了。

const int N = 1e5 + 7;

int n, m, w[N], ans;
struct Edge{int x, y, z;} g[N]; int fa[N], num[N];
ll sum[N];
inline int Find(int x) {return fa[x] == x ? x : fa[x] = Find(fa[x]);}
inline void Union(int x, int y) {
fa[y = Find(y)] = x = Find(x);
num[x] += num[y], num[y] = 0;
sum[x] += sum[y], sum[y] = 0;
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
read(n), read(m);
for (int i = 1; i <= n; ++i) read(w[i]), fa[i] = i, sum[i] = w[i];
for (int i = 1; i <= m; ++i) read(g[i].x), read(g[i].y), read(g[i].z);
std::sort(g + 1, g + m +1, [](const Edge &a, const Edge &b){return a.z < b.z;});
for (int i = 1; i <= m; ++i) {
int x = Find(g[i].x), y = Find(g[i].y), z = g[i].z;
if (Find(x) != Find(y)) Union(x, y);
++num[x];
if (sum[x] >= z) ans += num[x], num[x] = 0;
}
printf("%d\n", m - ans);
}

  后来到网上又翻了一会儿题解,发现我之前的方法还是有救的,而且还有两种解救的办法。

  第一种是通过不带路径压缩,只用按秩合并来做的并查集,这种并查集的单次操作的时间复杂度是 \(O(\log n)\) 的,而且因为没有路径压缩,可以很方便地实现 Cut 操作,比 LCT 好写,当然也就只适合这道题了,并查集扩展性没有 LCT 好。

  第二种是建立 Kruskal 重构树。那么在从小到大枚举最小生成树里面的边的时候,对于一条边,如果其父亲没有被删除,那么显然他自己也不需要被删除了。因此如果判断的话,首先判断其父亲有没有被删,然后再看看其所在联通块的点权和——其现在所在联通块就是在重构树上的子树!这样的方法,因为删边时一定是从根山道这条边的,所以不需要更该其祖先的子树和的信息。

  此上三中方法的时间复杂度都是 \(O(m\log n)\) 。我就只写了第一种。


F - Jewels

  想了两个小时也不会做,上网找题解也找不到,看来我可能需要去研读一下官方的英文题解。但是由于我英语比较烂,所以F可能要咕。

[AtCoder] NIKKEI Programming Contest 2019 (暂缺F)的更多相关文章

  1. AtCoder NIKKEI Programming Contest 2019 C. Different Strokes (贪心)

    题目链接:https://nikkei2019-qual.contest.atcoder.jp/tasks/nikkei2019_qual_C 题意:给出 n 种食物,Takahashi 吃下获得 a ...

  2. atcoder NIKKEI Programming Contest 2019 E - Weights on Vertices and Edges

    题目链接:Weights on Vertices and Edges 题目大意:有一个\(n\)个点\(m\)条边的无向图,点有点权,边有边权,问至少删去多少条边使得对于剩下的每一条边,它所在的联通块 ...

  3. AtCoder NIKKEI Programming Contest 2019 E. Weights on Vertices and Edges (并查集)

    题目链接:https://atcoder.jp/contests/nikkei2019-qual/tasks/nikkei2019_qual_e 题意:给出一个 n 个点 m 条边的无向图,每个点和每 ...

  4. [AtCoder] Yahoo Programming Contest 2019

    [AtCoder] Yahoo Programming Contest 2019   很遗憾错过了一场 AtCoder .听说这场是涨分场呢,于是特意来补一下题. A - Anti-Adjacency ...

  5. 【AtCoder】全国統一プログラミング王決定戦予選/NIKKEI Programming Contest 2019

    感觉最近好颓,以后不能这么颓了,要省选了,争取省选之前再板刷一面ATC??? A - Subscribers 简单容斥 #include <bits/stdc++.h> #define f ...

  6. NIKKEI Programming Contest 2019 翻车记

    A:签到. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> ...

  7. Atcoder Yahoo Programming Contest 2019 简要题解

    A-C 直接放代码吧. A int n,k; int main() { n=read();k=read(); puts(k<=(n+1)/2?"YES":"NO&q ...

  8. AtCoder AISing Programming Contest 2019 Task D. Nearest Card Game

    题目分析在代码注释里. int main() { #if defined LOCAL && !defined DUIPAI ifstream in("main.in" ...

  9. Sumitomo Mitsui Trust Bank Programming Contest 2019 Task F. Interval Running

    Link. There is a nice approach to this problem that involves some physical insight. In the following ...

随机推荐

  1. sed进阶

    下面这些命令未必经常会用到,但当需要时,知道这些肯定是件好事. 一.多行命令 sed命令通常是对一行数据进行处理,然后下一行重复处理. sed编辑器包含了三个可用来处理多行文本的特殊命令 N:将数据流 ...

  2. postman 简单使用教程

    Postman 安装   Postman 接口测试(Collection)   Postman 接口测试(测试用例)Postman 接口测试(变量与参数化)Postman 接口测试(非 UI 运行模式 ...

  3. 1204C Anna, Svyatoslav and Maps

    题目大意 给你一个有向图和一个路径 让你在给定路径中选出尽量少的点使得新路径的最短路长度和原路径相等 给定路径相邻两点间距离为1 分析 先floyd求出两点间最短路 之后每次对于点i找到所有跟它的最短 ...

  4. 如何正确安装Mysql

    1.官网去下载 2.针对操作系统的不同下载不同的版本  安装步骤: 第一步解压文件:位置为你想要安装的盘符第二步加载环境变量加载的是bin目录第三步初始化:在cmd终端中输入 mysqld --ini ...

  5. Hive presto和hive时间格式转换

    1.北京时间格式   to   unix时间格式 数据格式: 2017-11-17 08:28:13 2017-11-17 08:28:10 2017-11-17 08:27:51.343 2017- ...

  6. centos7安装MongoDB4.0(yum安装)

    1.添加 yum repo vi /etc/yum.repos.d/mongodb-org-4.0.repo 添加如下内容 [mongodb-org-4.0] name=MongoDB Reposit ...

  7. Nginx 转写功能和Apache .htaccess 对应

    之前一直使用apache 服务器,现有一项目想转到Nginx 服务器运行.. 发现Apache 的撰写功能和 Nginx的不一样.无法通用.hataccess 文件 查阅网上资料,nginx 配置转写 ...

  8. 从零搭建一个Redis服务

    前言 自己在搭建redis服务的时候碰到一些问题,好多人只告诉你怎么成功搭建,但是并没有整理过程中遇到的问题,所有楼主就花了点时间来整理下. linux环境安装redis 安装中的碰到的问题和解决办法 ...

  9. Node.js实战5:操作系统与命令行。

    Nodejs有一些内置的方法可以查询操作系统信息: 如: process.arch获取到系统是32位还是64位, process.platform可获取系统的类型. 例程: console.log(p ...

  10. CentnOS7安装Nginx“No package available”

    Nginx相对Apache有轻量级,简洁的优点,算得上Apache的优秀替代品了,但是由于Nginx不在yum的官方源中,因此安装时总会出现失败的现象,只需: yum install epel-rel ...