Codeforces Round #545 (Div. 2) 题解
A. Sushi for Two
题意
在一个 01
序列中找出长为偶数的连续的一段使得它前一半和后一半内部分别相同,而前一半和后一半不同。
\(2\le n\le 100\ 000\)
题解
令共有 \(k\) 段连续的区间,第 \(i\) 段区间的长度设为 \(a_i\),则答案是在求 \(\max_{i=1}^{k-1}\min(a_i,a_{i+1})\)。我因为没好好判 \(\min\) 而轻松地丢掉了 WA on pretest 4
的50分。
代码
标签
- 枚举
B. Circus
题意
有 \(n\) 个人,需要把它们分成两组,每组恰好 \(\frac n2\) 个人。每个人可能会技能 \(1\) 或技能 \(2\),一个人可能会其中一种、两种都会或什么都不会。
要求第一组中会技能 \(1\) 的人数恰好等于第二组中会技能 \(2\) 的人数,输出方案。
\(2\le n\le 5\ 000\)
题解
\(O(n^2)\) 的做法其实有些冗余,所以找到一种好理解的 \(O(n)\) 算法。
我们用两个 0/1
来表示一个人会的技能。比如一个人会技能 \(1\) 而不会技能 \(2\) 则表示为 0 1
。
由于 1 1
的限制比较大,而他在第一组或第二组都必须做出贡献,因此我们枚举 1 1
在第一组有 \(i\) 个,假定总共有 \(d\) 个 1 1
,则钦定第二组有 \(k-i\) 个 1 1
。
此时我们首先要把贡献较小的一边给补成 \(\max(i,d-i)\) 个,然后会分别剩下 \(a\) 个 0 0
,\(b\) 个 0 1
,\(c\) 个 1 0
。
如果 \(b>c\),可以考虑把 \(b\) 多出来的 \(b-c\) 个塞给第一组,则不做出任何贡献。
同理如果 \(c>b\),可以考虑把 \(c\) 多出来的 \(c-b\) 个塞给第二组,则不做出任何贡献。
但是会有一种情况,导致 \(\max(i,d-i)+|b-c|>\frac n2\),此时就会有一些不得不做贡献的人,理解为溢出。此时就会产生一些不得不做的贡献,是无论如何都补不回来的。
因此,当 \(\max(i,d-i)+|b-c|\le \frac n2\) 时,就有解。我们首先把 \(i\) 个 1 1
输出,如果 \(i<d-i\),需要先用 1 0
把它补到 \(d-i\),这也是要输出的。然后剩下的优先选 0 1
输出,最后拿 0 0
补齐。
代码
标签
- 枚举
- 构造
C. Skyscrapers
题意
在 \(n\times m\) 的网格上,每个格子都有一个权值。现在对于每个格子 \((i,j)\),问给第 \(i\) 行和第 \(j\) 列重新赋值为正整数,使得它们的原相对大小不变,问最大的正整数最小是多少。
\(1\le n,m\le 1\ 000\)
题解
我们发现第 \(i\) 行和第 \(j\) 列仅在 \((i,j)\) 处产生联系,其余都是独立的。
因此对于所有元素,可以在 \(O(nm\log n)\) 的时间里知道它在那一行/那一列的排名,行和列、大的和小的都要照顾到。假设它在那一行里排名为 \(p\),那一列里排名为 \(q\),则答案为 \(\max(p,q)+\max(m-p,n-q)\)。
代码
标签
- 排序
- 贪心
D. Camp Schedule
题意
给定串 \(s\),代表学生的计划,其中 0
表示这一天没写作业,1
表示这一天写作业了。
给定串 \(t\),代表最佳计划,其中 0
表示这一天不用写作业,1
表示这一天要写作业。
你可以改变串 \(s\) 的顺序,最大化 \(t\) 在 \(s\) 中出现的次数。
\(1\le |s|,|t|\le 500\ 000\)
题解
可以看出给出 \(s\) 相当于给出了 \(0\) 和 \(1\) 的个数,因此我们需要考虑 \(t\) 的构造。我们发现 \(t\) 在 \(s\) 中的出现是可以重合的,因此我们求出 KMP 中的 \(nxt\) 数组,我们只取前 \(n-nxt[n]\) 个。假设前 \(n-nxt[n]\) 个字符构成的字符串为 \(u\),令 \(u\) 中 \(0\) 的个数为 \(p\),\(1\) 的个数为 \(q\);令 \(s\) 中 \(0\) 的个数为 \(a\),\(1\) 的个数为 \(b\),则至少能构成 \(\min\left(\left\lfloor\frac ap\right\rfloor,\left\lfloor\frac bq\right\rfloor\right)-1\) 个 \(t\) 。
把这些构造完后,我们还会剩下一些 \(0,1\),而且还有一个 \(t\) 是不完整的,我们尽量与 \(t\) 匹配地接在它后面。这样输出就可以了。
求 \(nxt\) 数组和构造时间复杂度为 \(O(\mathtt{strlen}(s))\)。
代码
标签
- KMP
- 构造
E. Museums Tour
题意
一周有 \(d\) 天。一个人在一周的第 \(1\) 天从 \(1\) 号点出发,城市的地图是一个 \(n\) 个点 \(m\) 条边的有向图。这个人每天晚上要么结束旅行,要么往某个方向行走一步。每个城市有一个博物馆,只在每周的特定时间开放。问他最多能参观多少个城市的博物馆。
\(1\le d\le 50\)
\(1\le n\le 100\ 000\)
\(1\le m\le 100\ 000\)
题解
好题。
我们考虑把每一天拆成 \(d\) 个点,令第 \(i\) 号点在第 \(j\) 天的点为 \([i,j]\)。存在 \(\left<i,v\right>\),则让 \([i,j]\) 向 \([v,j\bmod d+1]\) 连边。
注意:博物馆不开放仅代表不做出贡献,不代表那天不能去那个城市。因此连边不能省。
然后我们可以在这个有向无环图上跑 tarjan 缩点。
可以证明,在新的 DAG 上的任意一条链中,原图的每个点只会出现在一个强连通分量里。
- 在连边后的图上,如果原图中的点 \([i,j]\) 向 \([i,k]\) 有连边,那么 \([i,k]\) 一定向 \([i,j]\) 有连边。因此在路径上可能出现的原图同一个点的新点都会被缩到同一个强连通分量里。
因此我们可以计算每个 SCC 的贡献。当给出的矩阵中 \([i,j]\) 为 \(1\) 时则做出 \(1\) 的贡献,\(i\) 相同的不重复统计。
然后计算从 \([1,1]\) 开始的权值最长路。拓扑排序可以完成。
但是由于一共有 \(5\times 10^6\) 个点,递归可能会爆栈,因此我写的非递归(码量有点大但是不是很难写)。
可以参考 Pinkrabbit 的递归超小空间解法。
代码
标签
- tarjan
- 拓扑排序
F. Cooperative Game
题意
交互题
现在有 \(10\) 个棋子。有一个图,是由一条长为 \(t\) 个节点的链指向一个大小为 \(c\) 的有向环的。其中除了 home vertex的入度为 \(0\),finish vertex 的入度为 \(2\),其余各点的入度均为 \(1\);同时,所有点的出度都为 \(1\)。
现在,每一步你可以选取一些点让它走一步到它出边指向的点。走完每一步以后,交互器都会告诉你哪些棋子在同一个点上。现在要你在 \(3(t+c)\) 步以内,把所有的棋子都移动到 finish vertex。
\(1\le t,c,(t+c)\le 1\ 000\)
题解
由于之前做过的交互题都是和倍增/二进制有关,本题给出了 \(10\) 个点,而且 \(\log_2 1000\) 也恰好是 \(10\),于是就这样陷进去了…
实际上我们只需要 \(3\) 个点就能解决本题的问题,我们可以把这 \(10\) 个点分为 \(0,1,23456789\) 三个部分。
首先让 \(0\) 每走 \(2\) 步,\(1\) 走一步。当 \(0,1\) 相遇时环长即为 \(0\) 走过的距离减去 \(1\) 走过的距离。每次 \(0\) 总比 \(1\) 快一步。除了一种情况以外,环长也等于 \(1\) 走过的步数。这叫做Floyd判环。
一种情况:
如果下一步是 \(0,1\) 一起走的话,那么 \(0\) 走的步数就不恰好是 \(1\) 走的步数的两倍了,因此需要判一下。
此时我们知道 \(0,1\) 在环上的某个点相遇了。我们现在知道了环长 \(c\) 和链长 \(t\),但是我们不知道 finish vertex 在哪里。
我们为了让 \(01\) 与 \(23456789\) 在 finish vertex 相遇,我们可以构造出环上的一个点。设 \(1\) 号棋子已经走了 \(m\) 步,因此令 \(01\) 在环上“倒退 \(m\) 步”,也就是前进 \(-m\pmod c\) 步,此时就和 \(23456789\) 同步了。我们发现,环长一般情况下也恰好是 \(m\)(特殊情况是 \(m+1\),让 \(01\) 先走一步就可以了),然后让 \(0123456789\) 同时移动。
最终所有点相遇的地方就是 finish vertex 了。输出 done
即可。
一般情况下步数为 \(2(t+c)-1\),上面提到的情况步数为 \(2(t+c)\)。
代码
标签
- Floyd判环
- 交互
Codeforces Round #545 (Div. 2) 题解的更多相关文章
- Codeforces Round #545 (Div. 1) 简要题解
这里没有翻译 Codeforces Round #545 (Div. 1) T1 对于每行每列分别离散化,求出大于这个位置的数字的个数即可. # include <bits/stdc++.h&g ...
- Codeforces Round #182 (Div. 1)题解【ABCD】
Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...
- Codeforces Round #608 (Div. 2) 题解
目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...
- Codeforces Round #525 (Div. 2)题解
Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...
- Codeforces Round #528 (Div. 2)题解
Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...
- Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F
Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...
- Codeforces Round #677 (Div. 3) 题解
Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...
- Codeforces Round #665 (Div. 2) 题解
Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...
- Codeforces Round #160 (Div. 1) 题解【ABCD】
Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...
随机推荐
- [C++] 2D Array's memory allocation
2D Array's memory allocation
- Pandas -- Merge,join and concatenate
Merge, join, and concatenate pandas provides various facilities for easily combining together Series ...
- Spring Boot利用poi导出Excel
至于poi的用法就不多说了,网上多得很,但是发现spring boot结合poi的就不多了,而且大多也有各种各样的问题. public class ExcelData implements Seria ...
- GitLab服务器IP地址修改
gitlab安装介绍:https://about.gitlab.com/downloads/#centos7 刚搭建好的gitlab在GitLab上新建一个项目test_gitlab,刚开始仓库地址是 ...
- javascript总结20: 前端必读,浏览器内部工作原理(转)
目录 一.介绍 二.渲染引擎 三.解析与DOM树构建 四.渲染树构建 五.布局 六.绘制 七.动态变化 八.渲染引擎的线程 九.CSS2可视模型 英文原文:How Browsers Work: Beh ...
- 编写高质量代码改善C#程序的157个建议——建议133:用camelCasing命名私有字段和局部变量
建议133:用camelCasing命名私有字段和局部变量 私有变量和局部变量只对本类型负责,它们在命名方式也采用和开放的属性及字段不同的方法.camelCasing很适合这类命名. camelCas ...
- 洛谷 P2146 [NOI2015]软件包管理器 (树链剖分模板题)
题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...
- BHO插件操作IE浏览器,js调用C#方法
BHO是IE浏览器的扩展程序,全名Browser Helper Object,文件格式为DLL文件.可对IE浏览器的界面和访问内容进行修改操作.BHO只适用于IE浏览器,对其他任何浏览器都没有作用.( ...
- 串口实现FIFO接受数据(V2)
在上一次的基础上添加了不同需求缓冲区大小可变的更改. /* * 串口的FIFO简单读取实现 * 功能,实现串口的FIFO实现 * 使用方法: * 更新时间:2017.9.26 * 版本:v2.0.0 ...
- ubuntu里面如何以root身份使用图形界面管理文件?
nautilus 是gnome的文件管理器,但是如果不是root账号下,权限受限,我们可以通过以下方式以root权限使用! 一,快捷键“Ctrl+Alt+t”,调出shell. 二,在shell中输入 ...