集训队作业 2020 题解
2020 集训队作业 题解
温馨提示:本文大概有 字(不包含任何代码)。
这份题解编码一下可以作为一个字符串题的输入
2013-2014 ACM-ICPC, NEERC, Northern Subregional Contest
C. Correcting Curiosity
Problem
对于串 ,定义 为:
- 如果 中不包含 ,则 。
- 如果 包含 ,找到 中 第一次出现的位置,设此时 ,则
给定串 ,长度为 ,你需要找到一对 ,使得 ,且 最小。输出一个方案。
Sol
显然需要进行替换,因此 是 的一个子串。
先枚举 ,求出所有长度为 的子串的hash值。然后枚举这个长度的所有子串作为 ,可以通过替换 的次数求出 ,然后可以通过字符串hash求出是否存在一个合法替换的方案。
复杂度
H. Heavy Chain Clusterization
Problem
给 个字符串 ,你需要将它们划分成若干个集合,使得对于每一个集合,以下两个条件至少有一个被满足:
- 集合中的所有串的前 位相同。
- 集合中的所有串的后 位相同。
求集合个数最小的一个方案,输出构造的方案。
Sol
对于合法的一个集合,它一定能被表示成一个长度为 的前缀/后缀,集合中的所有串都以它为前缀/后缀。
考虑先处理出所有可能出现的集合,可以发现一个点最多出现在两个集合中。
考虑两排点,第一排表示前缀对应的集合,第二排表示后缀对应的集合。对于每个点,从它的前缀对应的点向后缀对应的点连边。可以发现,每条边两侧的两个点对应的集合至少需要有一个存在。
因此答案为这个二分图的最小点覆盖。求出最大匹配直接构造即可。
具体来说,如果当前图有完美匹配,选一侧点即可。否则,找一个不在最大匹配中的点,它一定不在最小点覆盖中,因此与它相邻的点一定在最小点覆盖中。考虑删去与它相邻的点,则这些点在匹配上对应的点此时变为了不在现在的最大匹配中。一直做这个过程直到剩下一个完美匹配即可。
复杂度
I. Intellectual Property
Problem
定义数独题目为一个 的矩阵,其中每个位置为 间的整数或空白。
定义以下几种变换:
- 选择两个数字 ,将矩阵中所有为 的位置改为 ,所有为 的位置改为 。
- 选择两行 ,满足 在同一组中(所有行被划分成三组( ),列同理) ,交换矩阵的第 行和第 行。
- 选择 ,整体交换第 组的行与第 组的行,顺序不变。
- 选择两列 ,满足 在同一组中,交换矩阵的第 列和第 列。
- 选择 ,整体交换第 组的列与第 组的列,顺序不变。
- 将矩阵沿左上到右下的对角线翻转
给出 个这样的矩阵,求出它们两两之间是否可以通过变换使得两个矩阵相等。若相等构造一个方案。
Sol
考虑快速判断只有操作1是否合法。考虑记录每种数所在的位置的集合的hash,再对这些hash做一个无序hash。如果两个矩阵这样做出来hash相等则可以通过1操作做到相等。
显然6操作最多有一次,且剩下的操作之间顺序不重要。考虑对剩下的操作折半。对于每个矩阵,枚举它的列变换,算出hash值用hashtable维护。然后枚举每个矩阵,枚举是否翻转对角线,再枚举行变换,求出hash值,如果能对应上某个矩阵之前算出的hash值则可以从这个矩阵通过操作变到那个矩阵,否则一定不行。
为了保证复杂度,对于每个矩阵,不能向hashtable中插入相同的hash值。
复杂度
J. J
Problem
Sol
定义
将计算中的向量表示成 的形式,考虑所有操作:
对于向量加标量的情况,可以看成加 。
对于向量相加,可以看成多项式相加。向量相乘可以看成多项式相乘,向量平方同理。
可以发现一个表达式的complexity即为运算结果的最大次数。
考虑折叠操作,因为次数不超过 ,可以直接预处理 后求值。
可以先求出表达式中括号的匹配情况,然后直接计算即可。
复杂度
L. Lonely Mountain
Problem
水平面上有一座山峰,山峰在两个垂直于水平面且互相垂直的平面上的投影都形如一个山峰 -- 投影由若干个点 组成,满足 。
给出山峰在两个平面上的投影,求出山峰的最大体积或报告不存在合法的山峰。
设 为两个投影分别的点数,
Sol
如果两个投影的最高高度不同,显然无解。
考虑将每个点的高度设为两个投影上对应位置的高度的最小值,可以发现这样在最高高度相同的情况下一定合法,且得到的一定是最大值。
考虑从高度一维上计算,设 表示第一个投影高度大于等于 的区域长度, 表示第二个投影高度大于等于 的区域长度,那么体积为
可以发现 都是分段一次函数,直接算即可。
复杂度
2014-2015 ACM-ICPC, NEERC, Northern Subregional Contest
C. Combinator Expression
Problem
设表达式长度为 , 。
Sol
注意到如果没有 K
,每次只能消掉一个字符,此时操作次数固定。想让操作次数最小,显然需要让每个 K
消掉尽量多的东西。
因为表达式内部进行操作后长度只会变小,所以最优解一定满足所有被 K
消掉的区域内部不进行操作。
可以发现,从左向右直接进行化简得到的解满足这一条件,因此它是最优的,模拟这个过程即可。
复杂度
E. Expression
不会
F. Fragmentation
Problem
给一个长度为 的序列,你需要将其划分成若干段,满足将这些段之间重新排序后,可以使得整个序列递增。
求出一种段数最少的方案。
Sol
如果分在两个相同的数之间,一定可以调整使得分到旁边。这样可以使得最优解不在两个相同的数之间分段。
将相同的相邻数缩起来。考虑现在相邻的两个数 :
- 如果 ,显然需要分开。
- 如果 但还有数在 直接,也需要分开。
处理完一定分开的数后,考虑剩下的位置,可以发现还有两个限制:
- 对于所有相邻的 ,最多只能有一对 不被分开。
- 对于同一段内相邻的 ,若 中还有其它数,则这两对中最多有一对不被分开。
可以发现,满足上面的所有条件后,得到的划分方案一定合法。
考虑 ,设 表示考虑了前 对 ,第 段中的上一对没有分开,只考虑前面部分最少需要分开多少段。显然这样的状态数为 。
考虑转移,如果 ,则一定可以从 转移到 ,只需要判断是否可以从 转移到 ,这可以 判断。
复杂度
H. Hiking in the Hills
Problem
给一个山峰,山峰的表面由 个三角形组成。保证不存在中空的情况,也不存在一个三角形与水平面垂直。
给出你现在所在的位置以及你想要到达的位置,找到一条从现在的位置到目标位置路线使得路线上的最高高度最小。输出这样的方案。
Sol
除了起点终点外,如果经过了一个三角形的内部,考虑改为沿着三角形的边走,一定存在一种方式使得最高高度不会增加。
因此在中间部分只会沿着边走,可以发现起点终点只会向所在的三角形的顶点走。
因此现在的边数只有 条,排序后并查集维护即可。
复杂度
K. Kebab House
Problem
你需要处理 个物品,处理第 个物品需要 秒,每一秒你都会进行一次操作。
但是你可能忘记进行操作,你在任意 次相邻的操作中最多忘记一次。
如果你在处理第 个物品时进行了至少 次操作,则这样的操作是合法的。
求出合法的操作情况的总数,模
Sol
考虑dp,设 表示处理完前 个物品,上一次忘记是在 秒前 (若 ,则全部看成 ) 的方案数。
转移时枚举下一个物品最后一次忘记的时间,然后相当于求出一段时间内忘记不超过 次的方案数,可以组合数+前缀和求出。
复杂度
2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest
D. Distribution in Metagonia
Problem
给定 ,你需要将 划分成若干个数 ,满足:
构造任意一个合法方案。
多组数据,
Sol
如果 则构造 的解并全部乘上
考虑找到最大的 ,使得
如果 ,则选出 ,构造 的解,并将这些数全部乘上 。
否则,一定有 ,可以发现 ,所以使用同样的方式构造即可。
复杂度
F. Fygon
Problem
Sol
容易证明,有 个题目中描述的循环的程序的复杂度不超过 。
因此答案一定是一个不超过 次的多项式,考虑枚举 ,算出答案并插值。
总的运行次数不超过 ,因此直接模拟循环即可。
复杂度
G. Graph
Problem
给一个 个点 条边的DAG,你需要再加不超过 条边,使得这个图还是一个DAG且它字典序最小的拓扑序的字典序最大。
输出满足条件的方案和字典序。
Sol
考虑逐位确定,如果当前有多个点度数为0,考虑向最小的一个点连一条边(连向它的点暂时不决定),这样最小的值会变大。
维护当前所有连了这种边的点的集合,对于每一位,依次考虑:
- 如果当前有多个点度数为0并且还有边,向最小的一个点连一条边。
- 如果当前没有点度数为0,将集合中最大的点设为从拓扑序上一个点连向它,此时它变为度数为0的点。
- 如果集合中最大的点比当前度数为0的点还要大并且还有边,将集合中最大的点拿出来,然后进行操作1。
这样就保证了每一位最优。
复杂度
I. Insider’s Information
Problem
给定 ,给 个三元组 ,对于一个排列 ,这个三元组被满足当且仅当排列中 在 中间。
求一个排列 ,使得至少有一半的三元组被满足。
Sol
如果能找到一个排列,使得对于每个三元组, 不在 的后面,那么接下来每次贪心放满足尽量多的限制即可。
但是我不会找这个排列
考虑随机化爬山,每次随机一个数,把它放到使得满足数最大的位置上。
使用一些数据结构维护,修改一个数的复杂度为这个数所在的三元组个数。然后跑得飞快。
K. Kingdom Trip
Problem
有 个点 ,你能从 走到 当且仅当 ,且对于所有 , 到线段 的距离不超过 。
求从 走到 最少需要走几次。
Sol
考虑如何判断到射线 的距离不超过 。枚举 ,再依次考虑每一个 。如果 则 到射线的距离不会大于 ,否则它会限制射线的角度在一个区间内。
因此直接扫过去,维护当前所有区间的并。因为一个区间不超过180度所以区间的交只有一个区间。
然后再反向做一遍,求出是否每个点到射线 的距离不超过 。可以发现如果两个条件都满足则满足到线段距离不超过 。
复杂度
2016-2017 ACM-ICPC, NEERC, Northern Subregional Contest
B. Boys and Girls
Problem
个人排成一个环,其中有一些是男生有一些是女生。你需要构造一个方案,使得有 个人至少和一个男生相邻,有 个人至少和一个女生相邻。构造一个方案或输出无解。
Sol
将两种人看成 RB
。
特判 或 的情况,剩下的情况必定两种人都有出现。
考虑一个长度为 的极长连续 R
段:
- 如果 ,则这一段会贡献 个与
R
相邻, 个与B
相邻。 - 否则,则这一段会贡献 个与
R
相邻, 个与B
相邻。
一个 的段会使 增加 ,否则增加 ,因此可以根据 算出 的段数(奇偶性不同则无解)。设这个段数为 。
这 段至少会贡献 个 ,因此 无解。
若 为偶数,则放 段形成一个环,然后把剩下的 BR
放到某些段里面即可。
否则,需要额外一个长度为 的段。可以发现只有一个时是最优的。枚举长度为 的段是哪个,然后判一下即可。
复杂度
D. Digital Addition
Problem
Sol
从低到高考虑每一位。可以发现后面的位只有最左边的一排会影响前面的结果。
考虑dp,设 表示填了后 位的数,当前后面的加法是否进位,当前后面最左边一排的情况为 ,是否可以到达这样的状态。
然后记录转移输出方案即可。
复杂度
E. Easy Reading
Problem
给一个长度为 的字符串,选定这个字符串的一个子串,依次考虑子串的每一个字符。
你初始在 ,如果当前字符为 u
, d
, l
, r
,则你向上/下/左/右走一步,否则不进行操作。
在考虑完所有字符后,将所有你经过过的位置涂成黑色,这样可以得到一个图形。
给一个 的图形,你需要找到一个子串,使得考虑这个子串后得到的图形经过平移与给定图形相同,或说明无解。
Sol
考虑从串的开头开始走,但只把选定区间内经过的位置染色。
可以发现这样得到的结果平移之后就是题目中方式的结果。
考虑从小到大枚举 ,维护当前每个位置上次出现的时间。设给出的图形有 个染色的格子,则只需要判断上次出现时间最近的 个位置是否能组成合法的图案即可。
考虑记录 作为hash值,选择 个位置中的一个,将整个图形平移使得这个位置移动到 ,这时的hash值即为之前的值除以一个数的结果。
预处理出将给出图形的每个染色位置平移到 时得到的hash值,如果上面得到的值与其中的一个相同则这个图形可以通过平移得到原图形。
复杂度
G. Gangsters in Central City
Problem
给一棵 个点以 为根的有根树,初始所有点都是白色。 次询问,每个选择一个叶子,翻转它的颜色。
每次询问之后你需要找到一个删边的方案,使得删边后根不与任意一个黑点连通。你需要满足删的边尽量少,在这个基础上根所在的连通块尽量大。输出最优方案的删边数与此时不与根连通的白点数量。询问之间独立。
Sol
考虑根的每个子树,如果子树内有黑点则这个子树至少需要删一条边,否则不需要删边。
因此每个有黑点的子树需要删一条边,显然这条边应该是子树内所有黑点的LCA与它父亲的连边最优。
于是维护黑点的dfs序顺序,取最大最小做LCA即可。
复杂度
H. Hard Cuts
Problem
给一个 的矩阵,你需要将它分割成若干个边长为正整数的正方形,使得正方形的个数最少。输出方案。
多组数据
Sol
可以写点dfs,然后优先放边长大的,并在dfs的过程中通过估算至少需要的正方形数进行剪枝。
有一个显然不对的dp:枚举一条分割线分开。但可以通过这个dp得到的上界加速剪枝。
这时可以发现这个dfs需要跑三四个小时,但总的输出只有 ,压缩成字符后只有 ,打个表就过了。
I. Integral Polygons
Problem
给一个 个点,所有点坐标都是整数的凸多边形。求有多少条对角线满足沿对角线切开后得到的两个凸多边形面积都是整数。
Sol
特判整个多边形面积不是整数的情况,之后只需要考虑一侧面积为偶数的方案数。
设点为 ,分隔线为 ,那么一侧的面积为 ( 表示叉积 )
注意到这个值只和 的坐标奇偶性有关,考虑枚举 两维坐标的奇偶性,算出每个 的贡献 。
然后相当于对于每个合法的 求出有多少个 满足 是偶数,对 前缀和即可。
复杂度
J. Java2016
Problem
Sol
考虑设 ,在取 个的情况下,可以使得它有大约 的概率取 。构造 可以使用倍增构造。
然后再用若干个 加起来得到 即可。这部分也可以倍增构造。总的步数为
2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest
C. Consonant Fencity
Problem
给一个长度为 的字符串,你需要给除去 aeiouwy
的每种字符分配一个大小写,使得相邻且都不是 aeiouwy
,且大小写不同的字符对数尽量多。输出方案。
Sol
预处理两种字符相邻的对数,然后直接枚举大写的字符集合。
复杂度
D. Dividing Marbles
Problem
有一堆 个石头,你每次可以选择一堆石头,将其分成两份。每次操作后,如果有多于一堆石头的数量相同,则只会保留一堆。当只剩下一堆一个石头时游戏结束。
你需要求出最少的操作次数以及一个方案。
多组数据
Sol
考虑反向做这个过程,依次记录每次操作的数,可以得到一个序列 ,满足:
依次考虑每一个bitcount:
若 ,因为每一次最后一个数最多乘2,所以次数最少为 次。这显然可以达到。
若 ,可以发现次数最少为 次,先倍增 次,最后一次加即可。
若 ,使用类似刚才的方式可以得到 次的做法。如果存在 次的做法,则考虑第一个满足 的数,这之后每一个数的 必须加一。可以发现这时无法构造出 的数,因此上面的方式为最优解。
若 ,直接构造为 步,但存在一些数可以用 步求出 (比如 )。
考虑直接dfs出所有可能的 。因为可以构造出 步的方案,因此只需要搜 步的情况。可以剪枝消去大量无用情况,这样可以通过。
同时也可以正向dfs,通过类似的方式剪枝。可以发现每个时刻最多有两堆石头,因此可能的状态数非常少,也可以通过。据说直接打表可能的情况都能卡进200kb
E. Equal Numbers
Problem
有 个数 ,你可以进行若干次操作,每次你可以将一个数乘上一个正整数。
对于 ,求出进行 次操作后,现在的数的种类数的最小值。
Sol
设初始的数中最后不存在的数的集合为 。
如果对于每一个 ,都存在 。则可以将每一个 乘上一个数变成 ,这样不会多出别的数。
否则,一定做不到不多出别的数。因此可以将所有需要换掉的数变成它们的LCM。
首先考虑第二种情况的最优解,此时所有数都可以选,按照每种数出现次数排序然后贪心即可。
对于第一种情况,如果 满足 ,则此时一定不能选 。
如果 ,看成连一条 的有向边。这样得到的是一个DAG,且上面的数是所有度数为0的点。可以发现剩下的数全部放入 是合法的。因此不考虑上面的那些数再做一次贪心就是情况一的答案。
复杂度
F. Fygon 2.0
Problem
Sol
设所有的循环变量为 ,对于一个 for in range() 的语句,相当于要求 。
那么 相当于满足所有上面的条件的 的解数量。
考虑没有等号的情况, 时,可以看成所有数都在实数上随机,因此此时只需要考虑所有 种大小关系并判断哪些合法。这个可以使用状压dp+位运算做到 。
对于存在等号的情况,可能出现若干个数必须相等的限制。先进行一次强连通分量求出所有必须相等的变量,然后缩起来后用上面的做法即可。
复杂度
G. Grand Test
Problem
给一个 个点 条边的无向图,你需要找到两个点,使得这两个点之间存在三条除起始点外点不相交的路径。输出无解或找出一种方案。
多组数据,
Sol
先选出一个生成森林,找出剩下的边的端点在生成森林上的路径。
如果任意两条路径都边不相交,则图中的任意一个点双都是一个环,此时一定无解。
否则,找到两条相交的路径 ,找出它们的交 。
选择 为起点终点,第一条路径为树上路径,第二条为经过 的路径,第三条为经过 的路径。
复杂度
H. Hidden Supervisors
Problem
给一个 个点有向生成森林, 为根。你需要给剩下的没有父亲的点选一个父亲,使得得到的是一棵以 为根的有根树,且这个有根树的最大匹配最大。输出最优解以及方案。
Sol
假设确定好了树,则求最大匹配的过程可以dfs一次,每次贪心选最深的一对。
先求出每一个连通块的最优解。然后对于每个连通块,求出贪心匹配中根有没有被选以及没有被匹配的点数。
考虑剩下的连通块,如果一个连通块的根会被选,那么可以发现它的父亲无论是谁不影响答案。因此可以先贪心将这些接上去。
然后考虑根没有被选的,它们连到一个没有被匹配的点则会使答案+1。因此考虑优先连这种情况。
如果它连到一个被匹配的点,则上面的若干个贪心匹配会向下移动。但因为上面已经确定,所以不移动匹配得到的结果相同。
考虑贪心放,每次选出剩下的连通块中没有被匹配的点数最大的,将它连到前面,尽量连没有被匹配的点。这样可以得到更多的没有被匹配的点。可以发现这样是最优的。
复杂度
J. Joker
Problem
有一个长度为 的序列 ,设当前所有正数的和为 ,所有负数的绝对值的和为 。
定义 :若 ,则 ,否则 。
有 次操作,每次修改一个 ,你需要求出一个 满足 是 中最大的。若有多个选 最小的。
Sol
对于每个 记录前 个数中正数的和 ,负数的绝对值的和 。那么询问相当于求出 的最大值。
考虑对序列分块,对于每一块内部,维护只考虑内部的数,所有 构成的凸壳。这样修改时只用暴力重构一块,因为 递增所以重构复杂度线性。
对于一个询问,先求出 ,在每一块的凸包内二分找到最大的点即可。
复杂度
2013-2014 ACM ICPC Central European Regional Contest
A. Rubik's Rectangle
Problem
给一个 的矩阵,你可以进行若干次操作,每次翻转矩阵的一行或一列。
你需要使 ,矩阵的第 行第 列的元素为 。构造一组方案或输出无解。
多组数据,
Sol
将 看做一组。可以发现每次操作不会改变每一组内的元素集合。因此组内元素不正确无解。
考虑只交换某一个组内元素的方式。将这一组的元素标号为
考虑先翻转第 行,再翻转第 列,再翻转第 行,再翻转第 列,可以发现此时其余元素没有变化,而这四个元素的顺序变为:
因此对于一组,可以对三个元素进行旋转操作。可以发现这样每次操作不会改变排列的奇偶性,所有的偶排列都可以通过这种方式还原到初始情况。
接下来考虑每一组的排列奇偶性,称 在第 行第 列上。可以发现每次翻转一定会改变在一行或一列上的所有组的排列奇偶性。
这时相当于一个 的01矩阵,每次可以将一行或一列异或1,需要将整个矩阵变成0.
枚举第一行是否被翻转,然后可以知道每一列是否翻转,然后判断剩下的行是否合法即可。
将所有组变为偶排列后使用上面的方式求解即可。
复杂度
D. Subway
Problem
有 条地铁线路,第 条会依次经过 个站点。每一条线路都有双向行驶的列车,但到达终点站后换另外一个方向的列车算乘坐另外一次列车。
你需要从一个点到另外一个点,你需要乘坐列车的次数最少,在此基础上经过的站点数最多。求出最少次数和最多的站点数。
多组数据
Sol
首先处理掉极其过分的输入
考虑先求出到达每个站点的最少乘坐列车次数。对于每一条线路上的点,它们可以用一次互相到达。使用类似bfs的方式,当一条线路上一个点被访问到时更新整条线路上的点即可。
然后考虑算答案。设 为到达 最多的站点数。对于一条线路上的点,到达它们的最少乘坐次数相差不超过1。在这条线路上只能从次数小的点出发,到次数大的点。考虑按照次数从小到大处理,对于一条线路上的更新,从两个方向扫一遍即可。
复杂度
E. Escape
Problem
有一棵 个点的树,除了 外每个点上有一个数。你初始在 ,你有一个值 ,初始为 。
你可以沿着树边走,第一次经过一个点时,你的 会加上这个点上的数。如果 则你失败,随后这个点上的数变为 。
求你是否可以走到 并不失败。
多组数据
Sol
向 加入一个儿子,权值为 。则问题变为是否能经过所有点且不失败。
将每个数表示成 的形式,表示到达这个点先 再 。
考虑如何比较两个数哪个更优。根据贪心可以发现 的优于 的,对于所有 的,可以发现 更小的放在前面更优。对于 的,倒过来考虑,可以发现 更大的放在前面更优。
考虑当前最优秀的一个数,显然选择它父亲后下一步会选择它。因此可以将它与它父亲合并乘一个数。这样一直合并直到只剩一个数即可。此时有解当且仅当 。
复杂度
G. History course
不会
H. Chain & Co
Problem
在三维空间中有 个正方形框架,框架的宽度不计,没有两个框架相交且每个框架的所有边都与 轴中的一个平行,所有框架大小相同。
你需要求出是否可以将这些框架分成两组,使得从两组中分别选出一个框架,这两个框架都不是分离的。
多组数据
Sol
可以将框架分成三种:与 平行的,与 平行的,与 平行的。
可以发现同一类中的两个框架一定是分离的,所以同一类的必须在同一组中。
因此此时只有三种方案。考虑对于每两种框架,求出在两种中各选一个,是否它们都不分离。
考虑固定了两种框架,设框架大小为 ,可以发现,两个框架不分离当且仅当一个框架的左下角在另外一个框架左下角的 的区域内。因此求出所有区域的交即可。
复杂度
J. Captain Obvious and the Rabbit-Man
Problem
定义序列 。
给定 ,定义序列 ,其中 为整系数。
给出质数 , ,求
保证 模 两两不同余
多组数据
Sol
可以发现 是一个 阶线性递推,且特征根方程的所有根为 。因此特征根方程的为
先暴力求出特征根方程的系数,然后可以 推出下一项。
复杂度
2014-2015 ACM-ICPC, Central Europe Regional Contest
A. Parades
Problem
给一棵 个点的树,每个点度数不超过 。有 条路径,你需要选出若干条路径,使得选出的路径边不相交。求最多能选出多少条路径。
多组数据
Sol
考虑dp,设 表示 子树内能选出的最大路径数。为了转移再记录 表示 子树内,不能选 到 的最大路径数。
考虑 点上的转移。枚举每一条以 为 LCA 的路径,设路径为 ,它们分别在 子树内,假设选了若干条路径,则要求所有的 互不相同,且这时的路径数为
可以发现如果 则这条路径没有用。又因为 ,所以只需要记录是否等于,只有两边都是等于才会使得路径增加1。
然后相当于有若干对 ,需要找到最多的对数使得每个 只出现一次。这部分是一个二分图最大匹配,范围很小可以直接做。
然后再考虑转移 ,可以发现这相当于钦定一个点不选的二分图匹配。同样做即可。
复杂度
B. Mountainous landscape
Problem
给定 个点 组成的折线,对于每一个 ,求出最小的 ,满足射线 与线段 有交(交点为 上端点时认为无交)。
多组数据
Sol
考虑如何判断一条直线是否在一条折线的上方。求出这条折线的上凸壳,若直线与凸壳有交且交不是一个点则直线不在折线的上方。
问题相当于对于每个 ,找到右侧第一条线段,满足直线不在线段上方。
使用线段树,维护每个区间的上凸壳,然后在线段树上二分找。将所有射线按照斜率排序后按顺序线段树二分,则线段树每个点上的询问都满足斜率单调,因此可以均摊 询问。
复杂度
E. Can't stop playing
Problem
给出 个数 ,每个数都是 的非负整数次幂。有一个初始为空的序列,你会进行 次操作,第 次操作可以将 放到序列的任意一侧。若序列中存在两个相邻的相同元素,则这两个元素会合并成一个值等于原来元素值两倍的元素,并继续可能的合并过程。你需要使最后序列中只有一个元素。求出任意一个方案或输出无解。
多组数据
Sol
任何时刻如果序列中出现相邻三个元素满足 ,则之后 只可能变大,因此 不可能再合并,这种情况无解。
因此任意时刻序列是单峰的,因为每个元素都是2的非负整数次幂,这样的序列可以使用两个不超过 的二进制数表示。且总状态数不超过 。
因为合并时元素和不变,因此每个状态如果可以达到,则达到它时操作的次数固定。因此dp的总状态数不超过 。直接dp并记录转移即可。
复杂度
G. Virus synthesis
Problem
初始有一个空串,每次可以进行如下操作:
- 向串的一侧加入一个字符
- 设当前串为 ,将当前串变为 或 ,其中 为 翻转后的串
给定一个串 ,求将空串变为它的最小操作次数。
多组数据
Sol
每次2操作后得到的都是回文串,考虑只记录每次2操作后的结果,对回文串dp。
考虑从回文串 开始经过若干次操作1,最后一次操作2变为回文串 ,存在这样的操作当且仅当存在字符串 ,满足 。
因此相当于存在回文串 ,满足:
- 为 的回文后缀,且 。
考虑将dp看成最短路的形式,对于第一种情况,相当于对于每一个回文串 和字符 ,连边 ,边权为1。
对于第二种情况,相当于对于每一个 ,连边 ,边权为 。
此时一个转移可以看出若干步第一种边后再走一条第二种边。
可能的回文串一定是 的字串,建 的回文树,只考虑偶回文串,第一类边即为回文树的转移边。
对于第二类边,能转移到 的边即为 在fail树上的祖先中长度不超过 的串。这显然是一段前缀,可以进行树上前缀和优化连边。
然后最短路求出dp,因为合法路径必须以2操作的路径结尾,所以可以在最短路是额外记录一个值。
最后答案即为 。
复杂度
J. Pork barrel
Problem
给一个 个点 条边的图, 个询问,每次给定 ,求出只保留边权在 的边时,得到的边数最大的生成森林的边权和最小值。强制在线。
多组数据
Sol
显然 边的最小生成森林的边为 边的最小生成森林中边权不超过 的所有边。
将边排序从大到小加入,使用LCT维护最小生成树。这样即可维护每一个 的最小生成树。
然后使用主席树维护边权的变化即可在线询问。
复杂度
K. The Imp
Problem
有 个物品,第 个的价值为 ,费用为 。两人进行博弈:
第一个人可以选择一个物品(也可以不选择直接结束),支付 的费用,此时第二个人可以:
- 删去第一个人买的物品,之后让第一个人重新操作。这种操作最多进行 次。
- 不操作,此时游戏结束,第一个人的收益为最后选择物品的 减去过程中所有选择的物品的 的和。
第一个人希望最大化收益,第二个人希望最小化收益。求双方最优策略时的收益。
多组数据
Sol
问题可以看成第一个人选一个长度为 的序列 ,第二个人选一个 使得 最小。最后的收益即为这个值。
对比相邻元素可以发现,此时将第一个人的序列按照 从小到大排序最优。
因此可以将所有物品排序后从后向前 ,设 表示后 个元素选 个的最大收益,转移显然为 ,最后的答案即为 。
复杂度
L. Outer space invaders
Problem
有 个事件,第 个事件的出现时间为区间 ,它有一个权值 。
你可以在任意时刻选择一个正整数 ,花费 的代价,完成当前存在且权值不超过 的所有事件。
求让所有事件都完成需要的最少代价。
多组数据
Sol
首先对时间离散化,此时只剩 个时间点。
设 表示完成在时间区间 内的所有事件的最小代价。考虑区间中权值最大的事件,一定会进行一次操作完成这个事件。此时所有经过操作时间点的事件都会被完成,因此剩余的问题为两个子问题。使用记忆化搜索dp即可。
复杂度
2015-2016 ACM-ICPC, Central Europe Regional Contest
C. Cow Confinement
Problem
给一个 的网格,有 个栅栏,每个栅栏的形状为一个矩形的边界。任意两个栅栏没有公共点。
有 头牛和 朵花,每头牛只能向右或下走,且不能经过栅栏。求出每头牛能到达的花的数量。
Sol
对于每个栅栏内的情况分开做,先做一遍扫描线+线段树求出所有东西分别被哪个栅栏包含,这部分为 。
然后只需要考虑一个栅栏的情况,它内部的栅栏都可以看成实心障碍。
考虑从每一朵花的位置反向走,考虑一直向左,在不能向左的时候向上得到的路径,以及一直向上,在不能向上的时候向左得到的路径。
因为障碍没有公共点,这两条路径不会交错,因此这两条路径中间的部分除去障碍都是能走到的。
对向左的路径的下方减一,向上的路径右方减一,再对右下角减一,整体加一。则此时只有能走到的部分有加一。
分别处理四种情况。后两种非常简单。对于向左的路径,从右向左扫描线,维护扫描线右侧的所有花的位置开始向左走到这里的位置的权值线段树。显然加入一个障碍时相当于区间内的所有数全部移到一个端点的一侧。因此可以在 的时间内维护这个变化。询问一个位置单次显然是 ,另外一种情况同理。
复杂度
E. Export Estimate
Problem
给一张 个点 条边的简单图,每条边有边权 。
给 个询问,每次给定 ,每次进行如下操作:
- 删去所有边权小于 的边。
- 删去所有度数为 的点。
- 如果当前有一个度数为 且这两条边不是自环的点,则删去这个点并将这两条边连成一条边。重复执行这一步操作直到不存在合法的点。
求出操作后图的点数和边数。询问之间独立。
Sol
通过记录每个点相邻的边中边权最大的 条边,可以通过前缀和求出不进行最后一步的边数。
如果所有 度点都能被缩,则每个 度点会使点数和边数减一。唯一不能缩完的情况是存在一个由 度点组成的环。
只考虑每个点边权最大的两条出边,通过dfs可以找出可能出现的由 度点组成的环。
复杂度
F. Frightful Formula
Problem
有一个 的矩阵 ,给定 第一行和第一列的值,对于剩余的部分,有:
求出 ,答案模
Sol
首先考虑算出第一行第一列每个数对 的贡献,可以看成向右走一步权值为 ,向下走一步权值为 。则可以发现贡献形如 ,因此这部分可以在 时间内算出。
然后算出每个 对答案的影响,这部分为:
然后写个MTT就可以做完了
考虑看成倒过来走,则变为从 向左向上走若干步,不能经过第一行第一列。
算出走不超过 步的方案数减去出界的方案数。因为出界就再也不能走回来,枚举出界的位置,可以发现出界之前的方案是一个组合数,出界后就没有其他限制,没有限制走若干步的方案可以递推。
复杂度
G. Greenhouse Growth
Problem
有一个长度为 的序列 ,进行 次操作,每次操作为以下两种之一:
- 从左向右依次考虑每个位置 ,如果 ,则让 加一。
- 从右向左依次考虑每个位置 ,如果 ,则让 加一。
求出操作后的序列。
Sol
维护所有 相同的连续的段以及相邻两段的差。
对于一次1操作,如果一段满足这一段左右的值都大于它,则这一段与下一段的差会减少1,一段满足这一段左右的值都小于它,则这一段与下一段的差会减少1。
对于一次2操作,可以得到类似的答案。
可以求出每一对相邻的段在两种操作时差会不会减少。在两种操作的时候,可以找出所有差变为0的段,此时合并两段,并修改左右段的差的情况。
复杂度
I. Ice Igloos
Problem
给 个圆,第 个圆的圆心为 ,半径为 。其中 都是整数。
次询问,每次给定一条线段,求与这条线段有交的半径个数。
所有圆圆心不同
Sol
因为 ,与一条线段可能有交的圆心位置只有 个。
枚举圆心的 ,可以得到可能的 区间,然后直接枚举即可。
复杂度
J. Juice Junctions
Problem
给一个无向图,每个点度数不超过 ,求所有点对间最大流之和。
Sol
显然最大流等于最小割。
最大流等于 的情况非常简单,考虑一个连通块的情况。
取一棵生成树,考虑边双的做法,将所有非树边对应的树上路径覆盖。只留下树边中被覆盖的边,则此时还连通的点对最小割大于等于 ,否则为 。
考虑什么时候最小割等于 ,第一种情况为割一条树边和割一条非树边的情况,可以发现此时割掉的树边一定是覆盖一次的边,且这些边都可以被割掉,因此可以分出这种情况下最小割为 的点对。
第二种情况为割两条树边。此时两条树边分出了三部分,这种情况下只需要考虑中间部分和剩余部分被分开的情况。
枚举一条边 ,让另外一条边不在 的子树中,考虑一个点在子树中的情况。考虑所有 子树内连向 子树外的边,另外一条边割去后与 相连的部分不能有这些边的另外一个端点。此时找到以 为根它们的LCA,一定需要割去LCA的子树。此时相当于能割掉的边只可能在一条链上。
同时,还需要满足不考虑 子树内连向 子树外的边和 子树内,割去这条边后能把两部分隔开。这个可以直接打标记解决。
因为一个点在子树中,只需要求出可能在中间部分的点。只需要找到最远的一条合法的割边,然后相当于子树内的点到中间区域的点最小割都是 。枚举每个中间的点,然后对 打标记,最后将标记下传。
同时,再对另外一条边在 的子树中的情况使用相同的方式找出中间部分,这部分打标记的区间为dfs序的一段前缀和一段后缀,可以前缀和+后缀和解决。
最后所有没有被标记的点对最小割都是 !!1
复杂度
L. Looping Labyrinth
Problem
给一个 的模板网格,其中有一些格子为障碍,剩余位置可以通过。
有一个无限大小的二维网格,其中位置 的状态等于模板中 位置的状态。
给定 个询问,每次给一个空位 ,求出从 是否能到达
Sol
考虑在模板上加入若干条边,其中 向 连边权为 的有向边,反向边权为 , 向 连边权为 的有向边,反向边权为 ,将这两条边看成一条无向边,图中原先的边边权为 。
可以发现,能到达 当且仅当存在一条路径以 结尾且路径上的边权和为
首先将边权为 的边缩起来,并删去与原点不连通的所有部分。此时只剩下 个点和边。
取出图的一棵生成树,考虑剩余的每条非树边在树上组成的环。可以发现,所有从原点出发到自己的路径都可以表示为这些环的一个线性组合。因此求出每个环的边权和。而从原点出发到一个点的路径可以表示为原点到这个点的树上路径加上所有环的线性组合。因此问题变为给定 个二维向量,询问一个向量是否能被这些向量通过线性组合表示。
可以发现,对于若干个二维向量,一定存在 ,使得 两个向量通过线性组合表示的向量集合等于给定的二维向量能表示的向量集合。
考虑加入一个向量 ,先将 做 维上的辗转相除,可以得到两个向量 。然后再对两个 上的向量做gcd即可。最后询问显然可以 求出。
复杂度
2016-2017 ACM-ICPC, Central Europe Regional Contest
B. Bipartite Blanket
Problem
给一个两边分别有 个点的二分图,每个点有点权,求出有多少个点集满足:
- 点权和大于等于
- 存在一个二分图的匹配,使得点集中的每个点都在匹配中
Sol
若一个点集满足条件2,则一定满足点集中左侧点部分存在一个到右侧点的完美匹配,右侧点部分同理。
如果一个点集满足这两个条件,考虑在第一个匹配中从左侧向右侧匹配点连边,在第二个匹配中从右侧向左侧匹配点连边。这样得到了一个每个点入度出度不超过 的二分图。
如果图中存在一个长度大于 的链,则显然端点不在点集中,一定可以将链换为若干个长度为 的环。
如果图中存在一个长度大于 的环,则因为它是二分图,可以将它换成若干个长度为 的环。
此时得到的都是长度为 的环,因此可以合并为一个匹配。因此满足这两个条件的点集就是合法的。
此时一个点集合法只需要点集中左侧点部分合法且右侧点集合法。由Hall定理,左侧一个点集存在完美匹配当且仅当任意子集满足右侧与这个子集相邻的点集大小大于等于子集大小。可以先求出每个集合是否满足与这个子集相邻的点集大小大于等于子集大小,然后再fwt即可对于所有点集求出是否存在完美匹配。
然后将左右两侧合法的点集按照权值大小分别排序,然后扫过去即可。
复杂度
D. Dancing Disks
Problem
有一个 的柱子矩阵,初始时左上角的柱子上放了 个大小不同的盘子。你可以进行若干次操作,每次选出一根柱子以及上面的若干个盘子,你可以将这若干个盘子拿出,翻转顺序,再放入它正下方或正右方的柱子。
你需要在操作后,所有盘子都在右下角的柱子上,且此时所有盘子按照大小排好了序。给出初始柱子上从上到下盘子的大小,求出一个方案。
Sol
考虑将若干个盘子在 位置从小到大排序,可以先将盘子分成若干类,在所有的 处从大到小排序。然后再通过多路归并的方式合并到 上。从大到小的方式类似。
考虑这样能排序多少个位置。设 表示 行 列能排序多少个盘子,则有:
可以得到 。但注意到通过特判 的情况,这两种情况都可以做到排序两个盘子。
此时可以得到 。因此使用这种方式可以通过。
复杂度
E. Easy Equation
Problem
给定 ,找到 个正整数三元组 ,满足:
且每个数最多在所有三元组中出现一次,所有数不能超过 。
Sol
首先可以得到一个初始解 。
考虑对这个解进行迭代,设 ,固定 ,可以发现
因此另外一个解为 ,因此可以直接迭代。
但直接迭代的解位数达到 位以上,注意到也可以对 进行迭代,得到的数不会变小。因此通过bfs的方式,每次对一组解的最小两个数迭代,如果与之前的解不同则算入解。此时的位数非常小但仍然需要高精。
复杂度
G. Geohash Grid
Problem
定义 ,即将 的二进制表示交替写下的结果。
给一个 的矩阵,其中第 行第 列的值为 ,这里行列从 开始编号。显然编号是不重复的。
给一个 个点组成的多边形,每条边平行于坐标轴。
给出 个询问,对于每一个询问,给出 ,你需要找到不超过 个区间,满足:
- 对于每一个多边形内部的位置,它的值都被至少一个区间包含。
- 这些区间中包含的整数数量尽量小
求出这些区间中包含的最小整数数量。
Sol
将多边形内的点标为 ,剩余标为 。
求出所有两侧都有 的极长 段的长度,显然选 个区间的最优解是少选最长的 个极长 段。因此只需要求出这些 段的长度。
考虑类似四分树的做法,将矩阵分成四份,显然每一份中值的大小为一段连续区间。因此可以求出每一份内的极长 段以及每一份中最小和最大的 位置值,然后合并,在当前区域全0或全1时停止。
但如果给出一个 的矩形,四分树的复杂度就是 的。
在分治过程中,可以只维护所有的边界。如果边界中只包含横向边或只包含纵向边,则此时分出的四个部分中横向/纵向部分一定相同,只有 种不同的部分,可以将相同的部分合并,递归一次并将求出的每一个极长 段的次数乘 ,可以将乘 的系数放在分治过程中。且若两部分都不是全 或全 ,则这些边界一定分成了两部分。否则只用递归一部分或不用递归。
因为只有 个顶点,只要区域内没有顶点就一定只包含一种方向的边,因此会分出 个这样的区域。每个区域向下递归最多再分 部分,每部分只会递归 步,因此总的复杂度为
然后询问前缀和预处理+二分即可。
复杂度
I. Invisible Integers
不会
J. Jazz Journey
Problem
有 个城市,你想要通过飞机进行一个长度为 的旅行,给出旅行的每一个点 ,你会依次经过每个点,且你一定会乘坐直达的飞机。
有 种机票,第 种机票从 到达 ,价格为 ,它还有一个种类 :
若 ,则这张机票只能从 到 一次。
若 ,则在使用机票从 到 后,还可以再使用一次从 到 ,但必须先从 到 。
求出完成旅行的最小花费或输出无解。
Sol
显然只需要考虑每一对 之间的情况,可以使用map处理出每一对之间四种机票的最小费用和这两点之间的旅行。
可以用 的票替代 的票。现在问题变为,给出一个 组成的序列( 代表一个方向的旅行, 代表另外一个方向),给出子序列 的代价,你需要将序列划分成若干个这样的子序列使代价和最少。
初始全部使用单程票,然后考虑加入双向的票,此时问题变为分别给出匹配 的收益,你需要在序列中匹配若干个 ,每个字符只能匹配一次,求出最大收益。显然最大的匹配对数一定是两种字符中出现次数最少的一种的出现次数。
可以发现,若钦定一个方向,先贪心匹配这个方向尽量多的对数,然后再贪心匹配另外一个方向,这样一定能匹配完。因此先贪心匹配收益大的方向,这样一定能让总收益最大。
复杂度
L. Lost Logic
Problem
有一个 个变量的 2-SAT 问题,给出这个问题唯一的三组解,求出一个限制不超过 条的 2-SAT 问题,满足它只有这三组解或输出无解。
Sol
根据在三组解中的值,可以发现只有 种不同的变量。
考虑求出每一种变量有没有出现过,每种变量只留下一个。然后贪心加入所有满足条件的限制。如果此时解的数量大于 显然无解,否则可以得到此时的解。这部分限制不超过 个。
对于每种剩下的变量,考虑加入 ,则这两个变量必须相同。因此只需要两个限制即可加入一个变量
复杂度 ,操作步数不超过
2017-2018 ACM-ICPC, Central Europe Regional Contest
B. Buffalo Barricades
Problem
有一个网格图,有 个关键点。
个人依次来到网格图上,第 个人的位置为 。所有人的横纵坐标不会相同。
每一个人会从自己位置向左,向下放栅栏,一直碰到别的栅栏或边界为止。定义这个人所在的区域为它的栅栏内部的连通块。
对于每个人,求出它到达时它所在的区域中的关键点数。
Sol
首先考虑求出最后每个人区域内的点数,从右向左扫描线,维护当前线上的每个位置属于哪个人。显然每个人只会占一段区间,使用set维护分界点,很好维护加入人和计算关键点的操作。这部分复杂度
然后考虑算出真正的答案,对于每个点,它加入时会减少原先包含这个点区域的点的答案。显然此时包含这个点的点为它右上角加入时间大于它的最小点。使用set维护支持在中间加入点的单调栈即可求出这个值。这部分复杂度也是
然后按照时间顺序计算答案即可。
复杂度
C. Cumulative Code
Problem
给一棵深度为 的满二叉树,点 的两个儿子为 ,根编号为 。求出它的prufer序(每次删编号最小的叶子,每次删去点的父亲编号形成的序列),设序列为 。
次询问,每次给定 ,求出
Sol
首先考虑构造prufer序的过程,考虑两种情况:
- 一个深度为 的满二叉树,根向父亲有连边(即根最后被删去),此时因为左子树任意编号小于右子树最小的叶子编号,因此一定是先做左子树深度为 的情况 ,然后是右子树深度为 的情况 ,最后删去根。
- 一个深度为 的满二叉树,根向父亲无连边,此时先删左子树,再删根再删右子树,因此为先做左子树深度为 的情况 ,然后删去根,最后是右子树深度为 的情况 。
因此可以在 的时间内找到prufer序中一个位置对应原来的点,这样的复杂度为
再考虑一个 ,设 表示情况 中一个深度为 的满二叉树构造的prufer序中,所有编号模 余 的位置的值的和。
dp过程中,根的值可能会变,但可以注意到若根的权值为 ,则任意的 都可以表示为 的形式。只需要维护这个形式即可。
考虑 的转移,情况 中为先做左子树再做右子树,最后做根。因此将 中的 换为 可以得到左子树的情况,将 换为 可以得到右子树的情况,然后可以 合并。因此可以 求出所有 。
然后再设 表示情况 中一个深度为 的满二叉树构造的prufer序中,所有编号模 余 的位置的值的和。此时 可以表示为 的形式。它的转移与 类似。
因为 ,计算的一定是位置编号模 余 的一段前缀。因此在二叉树上向下找到前缀的结尾节点,然后一次计算左侧的所有子树的贡献即可。
这样的复杂度为 ,因为 ,因此综合两种方式,单次询问复杂度为 ,总复杂度为
D.Donut Drone
Problem
给一个 的矩阵,矩阵的两维都是循环的,每个格子有一个权值。
有一个人初始在 ,他每次走一步会走到下一列中与它的横向距离不超过 的三个位置中权值最大的位置。
给出 次操作,每次操作为以下两种之一:
- 修改一个位置的权值
- 让这个人走若干步,求出他现在的位置。
保证任何时刻一个位置向后的三个位置不会出现权值相同的情况。
Sol
显然一次修改最多改 个位置的出边,因此可以维护每个点出边构成的基环树森林。
使用lct维护一棵有根树,并维护根是否有一条环边。在link和cut的时候判断是否有新的环边或者一条原来的环边变成了树边的情况。然后移动的时候判断是否会到根,到根之后在环上走即可。
复杂度 比Yazid的棋好写三倍
E. Embedding Enumeration
Problem
给一个 个点的树,你需要将每个点映射到 的网格上的一个点,使得映射满足:
- 点 映射到
- 树上不同的点映射到网格上不同的点
- 树上相邻的点对应的点在网格上相邻
求出映射的方案数,模
Sol
考虑从 到映射中最靠右的点构成的一条链,可以发现,树上除去这条链外,每个点最多有一个支链,每条支链只可能在分出去时分叉一次( 的支链不能在分叉),否则无解。
考虑找出这条链,考虑所有度数为 的点(有度数大于 的显然无解),此时除了最后一个度数为 的点有多种情况,其余支链上度数为 的点都可以按顺序找到。
考虑 ,可以发现每个度数为 的点处的情况只有以下几种(其中 ....
表示主链上部分, ..
表示支链部分:
....---x---.... ....---x---.... ....---O ....---x---.... ....---x---..
| | | | |
..---O O---.. ..---X---.... ..---O---.. ..---x---....
如果决定了每一个点的情况,那么最后的方案数只需要计数每一对相邻的点间的方案数,因此可以设 表示第 个度数为 的点状态为 时前面的方案数,转移可以做到 。
最后讨论结尾的若干种情况即可。
复杂度
I. Intrinsic Interval
Problem
给一个长度为 的排列, 次询问,每次给出一段区间,求出包含这段区间的长度最小的连续段。
Sol
显然在析合树上求出区间端点的LCA后根据LCA是析点还是合点分别判一下即可,可以做到 甚至 。
考虑一个相对简单的做法,注意到如果两个连续段相交但不包含,则它们的交也是连续段。因此对于一个询问 ,只需要找到最大的 ,使得存在一个以 结尾且包含 的连续段,则以 结尾一定是最优的。
首先求出 表示以 结尾的连续段最小的开头,因为连续段满足 ,且非连续段一定取大于,可以单调栈维护max和min,在线段树上找最小值即可 求出。
然后可以对于每个询问找到答案的结尾 ,再做一遍上面的做法,在每个 出枚举所有结尾为这个位置的询问,只需要找到 左侧第一个合法的左端点即可,这个也可以线段树上求。
复杂度
K. Kitchen Knobs
Problem
给 个长度为 的数字串,你可以进行若干次操作,每次你可以将一个区间内的串循环位移相同数量的位。
你需要使得每个串都取到所有它循环位移串中字典序最大的串,求最少操作次数。
Sol
如果一个串的循环节为 ,则这个串无论如何都是最优,可以直接删掉。
否则,这个串循环节一定为 ,因此只存在一个最优解。因此可以看成一个长度为 的串,你可以将一段区间内的数加上一个值,使得所有数都是 的倍数。
考虑差分,那么相当于有 个数,每次选择两个数以及一个 ,让一个加 另外一个减 ,使所有数都是 的倍数。
考虑将操作过的两个数连边,显然一个连通块内所有数和是 的倍数,且一个大小为 的连通块至少需要 步操作。
因此可以看成将这些数划分成最少个数的集合,每个集合和都是 的倍数,可以将所有数看成 。显然 可以单独分开。
如果一个集合中有两个和为 ,则将它们分出来更优。如果有两个集合中分别有一个数,它们和为 ,则可以将这两个数分出来一个集合,两个集合剩下部分合并。这样不会变差。因此存在一个最优解,使得每一对和为 的数都被单独分出。
此时最多还剩下 种数,可以 求出此时的最优解。
复杂度
L. Lunar Landscape
Problem
给 个正方形,第 个正方形的中心坐标为 ,它有两种情况:
- 它的所有边平行于坐标轴,边长为
- 它的所有边与坐标轴夹角为 度,对角线长为
求出它们的面积并。
Sol
首先考虑只有第一种正方形的情况,可以看成在中心位置附近的四个格子分别放一个可以向八个方向扩散 步的点,所有的扩散结束后被扩散到的格子就是被覆盖的格子。
扩散的过程可以使用bfs,记录每个格子上还能再扩散多少步,从大到小做即可。复杂度
然后考虑第二种情况,可以看成在中心附近四个位置向四个格子放一个向四个方向扩散 步的点,此时除了边界上不会被这个正方形完全覆盖的格子外都会覆盖了。
然后考虑剩下的部分。只考虑第二种情况覆盖的格子,对于一个没有非覆盖的格子,如果它附近两个连续的方向(例如左上)的格子都在之前被覆盖了,如果这两个格子属于同一个正方形,则可以标记这个格子这个方向的一个角被覆盖了,否则,这个格子四个方向都被覆盖了,则这个格子无论如何都会被完全覆盖,因此也可以标记。最后对每个格子四个方向的标记情况可以算出这个格子被覆盖的面积。
复杂度 ,只需要bfs两次。之前写了个bfs五次的做法然后没跑过去
2013-2014 ACM-ICPC Northeastern European Regional Contest
A. ASCII Puzzle
Problem
Sol
直接写一个dfs,如果当前已经填的部分中有不能被填上的空位就判断无解,然后就能过了。
因为角块已经确定,边块只可能同一对互换,因此可能的状态数只有 。因此直接dfs是可行的。
C. Cactus Automorphisms
Problem
给一个 个点 条边的仙人掌,求有多少个点的排列 ,使得图中 间有边当且仅当 间有边。即计算这个图的自同构数。
你需要输出答案因式分解后的结果。
Sol
对于树的情况,考虑取出重心,对于每个点,只可能整体交换它的儿子。
使用树hash求出每个子树的hash值,对于每个点,如果它两个儿子的hash值相同则可以交换。显然最后交换的方案数为若干个阶乘的乘积。
如果树有两个重心,则还需要计算交换重心的情况。
考虑仙人掌上的情况,建出圆方树,考虑圆方树上做树同构,此时与树hash不同的情况如下:
- 对于一个方点,它的儿子顺序只能翻转不能打乱。因此计算点hash值时不能对子树hash排序,只能在两种顺序中取一个较小的。
- 圆点和方点的权值必须不同。
- 若存在双重心的情况,只有是两个圆点的情况才能互相交换。
- 若只存在一个重心且重心为方点,则此时需要计算重心所在的环上进行旋转的方案数。这个可以使用
KMPhash求出循环节并算出方案。
显然,最后的答案仍然是若干个阶乘的乘积再乘上1~2个数。对于阶乘的分解可以暴力,复杂度
总复杂度
D. Dictionary
不会
E. Easy Geometry
我可能会但我不想写
G. Green Energy
Problem
某地的地平线可以看成一条由 个点 组成的折线 。在这里,太阳光线与水平线的夹角为 度,从左向右照射 。
有 个太阳能板,第 个可以看成一个高为 的线段,它只能垂直于水平线放置。
太阳能板和地平线都会遮挡光线,你需要构造一种方案,使得被光线照射到的太阳能板长度和最大。输出最大长度和方案。
Sol
考虑光线水平的情况。此时的最大长度不会超过太阳能板最高的高度和能照射到的最低高度的差。
最低高度显然为地平线第一个点的高度,最高高度不会超过地平线最高点加上最长的板的长度。
因此答案不会超过所有板长度的和和这个差的最小值。
拿出最高的一块板,考虑贪心放其它的。将第一块板放在第一个点,然后将第二块板放在第一个会被照射到的地平线位置上,剩余同理。然后将最高的板放在最高的位置上。
易证这样放可以取到最优值。在放的过程中记录之前的板的最高高度即可 的求出方案。
在非水平的情况时,可以通过对坐标做一个变换,得到不改变答案的水平的情况。因此上述做法对于非水平的情况也是正确的。
复杂度
H. Hack Protection
Problem
给一个长度为 的序列 ,求它有多少个非空区间满足区间的xor值等于区间的and值。
Sol
枚举右端点,记 ,则 的xor值等于 。
显然,以 结尾的区间,不同的and值最多有 种,且每一种取值的左端点形成一段区间。
枚举每一个区间,那么相当于询问区间中 等于某个数的数量。可以使用各种数据结构解决。
复杂度
I. Interactive Interception
Problem
交互题,给出 ,交互器在 中分别选出一个数 ,有一个数 初始等于 。
你可以向交互库进行询问,你可以给出 ,交互库会返回 是否在区间 中,随后将 加上 。
你可以进行不超过 次询问,你需要求出当前 的值。
Sol
考虑二分,设当前时刻为 ,找出当前所有未被排除的解中 的中位数,然后询问 是否小于等于中位数。这样期望只需要 轮。
记录每个 对应的合法的 ,它一定是一段区间。然后找中位数的过程可以二分。
询问次数 ,复杂度 。
也可以直接取平均数询问。因为剩余的图形是一个凸包,因此取平均数询问近似于取一条经过凸包重心的直线,它也能在 轮求出答案,这样的复杂度为 。
K. Kabaleo Lite
Problem
有 个位置, 个人, 种颜色。初始时每个位置有一个颜色。
个人每个人有一个颜色,每人轮流操作,每个人可以选择一个位置将这个位置的颜色换为自己的颜色。
第一个人胜利当且仅当颜色 出现的次数严格最多。求出第一个人所有的可能的操作,使得这样操作后剩下的人无论怎么操作第一个人都必胜。
Sol
对于 的情况,可以特判。
对于 的情况,考虑最差操作。考虑让每个其他的人都去覆盖一个颜色 的位置。如果最后只剩不超过 个颜色 则显然无解。否则一定每次都能覆盖一个颜色 。
如果此时有解,则可以发现这种情况必胜。可以发现第一个人的操作只会改变两种颜色的出现次数。且是一个增加一个减少。因此可以只记录覆盖后颜色 的出现次数和另外的颜色中出现次数最多的两种。
然后可以得到操作后得到的覆盖后颜色 的出现次数和另外的颜色中出现次数最多的一种的出现次数。这样即可 判断一种操作是否必胜。
复杂度
2014-2015 ACM-ICPC Northeastern European Regional Contest
C. Cactus Generator
Sol
首先考虑求出这个仙人掌。因为边数有限,因此暴力模拟的复杂度是对的。可以使用dfs的方式,设 表示处理字符串 构成的图,其中所有变量的值为 是构造图的过程。除构造这部分外只需要再返回这部分的FL两个点即可。
预处理括号匹配,合并FL节点时使用并查集,这部分的复杂度为 ,其中 为构造出的边数。
然后考虑将其分成最少条数的路径。显然最小路径条数为 ,其中 为奇点的数量。
将奇点两两配对,每一对连边。这样得到的图不存在奇点,因此存在欧拉回路。对于一个欧拉回路,将之后加入的边删掉可以得到若干条路径。可以发现这些路径满足题目要求的条件。
因此问题只剩求出一个图的欧拉回路。先从每个点开始dfs,得到从每个点出发的环。然后再从一个环开始,将所有的环拼接起来。
复杂度
D. Damage Assessment
Problem
给一个立体图形。图形中间为长度为 ,圆的直径为 的圆柱体,两侧均为一个半径为 的球的球切,满足切面的直径为 。
将图形如图摆放,其中圆柱两个上下面的圆心高度差为 ,将高度不高于下面圆的最低点高度加上 的部分称为阴影部分。求出阴影部分的体积,绝对误差不超过 。
,,所有数字只有两位小数。
Sol
考虑以圆柱体分三部分,对于下面一部分算空的体积,对于上两部分算满的体积。
然后这个体积还是很难算,考虑 Simpson 积分,算截面的面积可以各种分类讨论之后求出,然后直接 Simpson。
复杂度不会证但是跑得挺快的
E. Epic Win!
Problem
两个人在用自动机进行游戏,游戏的操作有三种,称为 ,其中 胜 , 胜 , 胜 。若双方操作相同则这轮平局。
自动机上的每个状态包含这个状态上进行的操作 ,以及对手这次操作为 时下一个状态的编号 。
给出对手的自动机,对手的自动机一共有 个点。你需要构造一个不超过 个点的自动机,满足若你的自动机以 为起始状态,无论对手自动机的起始状态是哪一个,你都能在前 轮中至少赢 轮。
Sol
将构造的自动机的每一个状态设为此时对手可能所在的点的集合。起始状态的集合即为全集。
考虑构造一个点集对应的状态的转移。如果对手可能在的点的集合中的 不同,则这一步操作任意,否则,这一步走能赢对手的 的操作。
之后根据对手不同操作将点集分成三部分,每一部分作为一个后继状态集合。对于每一个状态递归构造。
若存在对手操作不同的情况,则集合一定会分裂,分裂最多有 次,因此一定能赢 次。
但如果集合一直不分裂,通过构造一些长度不同的环,状态循环的长度可能达到 级别。
但可以注意到此时操作一定会循环,操作循环节不会超过 ,因此若对于一个集合向后 步都没有分裂,则找出循环节连边即可。
复杂度 ,点数
G. Gomoku
不会
H. Hidden Maze
Problem
给一棵有边权的树,求出所有长度为奇数的路径的边权中位数之和除以长度为奇数的路径数量的值。
保证树随机生成。生成方式为每次随机一条边,若能加入则加入。
Sol
考虑转成 上的问题,相当于初始边权全为 ,每次把一条边权改为 ,求出此时新增的长度为奇数且边权和大于 的路径数量。
可以发现,新增的值即为经过这条边且修改后边权为 的路径数量。
考虑 ,设 表示 子树内到 的路径权值和为 的路径数。
在修改一条边时,先在它的所有祖先中减去子树内贡献的 ,然后加上修改后的 。
然后考虑算新增的贡献,依次枚举路径的LCA,再枚举子树内的边权和即可计算。
可以发现计算一次的复杂度为以这个点为根子树内最大深度乘以这个点的深度。
通过我不会的证明,可以得到随机情况下这个值为
复杂度
I. Improvements
Problem
给一个长度为 的排列 ,你可以进行若干次修改,每次可以修改一个位置的值,可以将其改成任意实数。
定义序列 是合法的,当且仅当考虑所有区间 ,它们中的任意两个区间要么不相交,要么一个包含另外一个。
求出让它合法的最小修改次数。
Sol
考虑未被修改的部分。可以发现将区间 替换为区间 时,若替换前合法则替换后一定合法。因此只保留未被修改的点必须合法。
同时如果将所有被修改的位置都改为与上一个未被修改的位置相同的值,则若只保留未被修改的位置合法,则这个方案一定合法。因此只需要求出可能的最多的未被修改的点数。
使用归纳法可以证明,对于合法的序列,一定满足每个位置都是后缀最大值或后缀最小值。因此它的权值构成一个 >
型。
此时可以发现将原序列翻转后接在原序列后,则每一个这样的序列都对应一个LIS。求这个序列的LIS即可。
复杂度
2015-2016 ACM-ICPC Northeastern European Regional Contest
B. Binary vs Decimal
Problem
定义一个数是好的,当且仅当它为非负整数,且它的十进制表示是它的二进制表示的后缀。
求出第 小的好数。
Sol
因为 ,因此改变十进制的一位只会改变二进制在这之前的位。因此一个数合法当且仅当它的每一个后缀合法。
因此可以枚举答案的位数,维护这个位数上所有可行的后缀。向下一个位数转移时只需要枚举十进制下一位填0还是1,手写高精度即可。
设答案位数为 ,则直接做高精的复杂度不超过 。可以发现 时 。
C. Cactus Jubilee
Problem
给一个 个点 条边且连通的仙人掌,你需要删去一条边再加上一条不同边,使得得到的图是一个无重边且连通的仙人掌。
输出可能的操作方案数。
Sol
考虑去掉不同边的限制,这时答案会增加 ,减去这些值即可。
对图建圆方树,考虑这条边的情况:
首先考虑删去割边的情况,此时两侧不连通,一定需要加边将两部分连接起来。求出两边点数即可。在圆方树上很好维护。
然后考虑删去环上边的情况,此时剩余的图还是一个仙人掌。需要在仙人掌上加一条边。可以发现如果一条边的两个端点在圆方树上的路径经过了方点,则加入这条边时会使图不是仙人掌。否则图还是仙人掌。
删去圆方树上所有方点,方案数即为每个连通块内连边的方案数之和。因为此时的连通块是树,显然一个 个点的连通块的方案数为 。
可以发现删去一个环边后只有这个环不再是环,因此此时这个环上的所有圆点会连通。枚举删去边的环,算出将环上点的连通块合并后的方案数即可。
复杂度
D. Distance on Triangulation
Problem
给一个 个点的凸多边形以及它的 条对角线。这些对角线形成了一个凸多边形的三角剖分。
只考虑多边形的边和对角线形成的边。设所有边权都为 , 次询问每次询问两点间最短路。
Sol
考虑分治。取出一条对角线,这条对角线可以将多边形划分成两部分。分别求出对角线端点到多边形内部的最短路。
对于两个点在两部分的情况,它的最短路一定经过这条对角线的端点。因此可以直接算出它的最短路。
否则,它的最短路如果经过另外一部分,则一定经过这条对角线的端点。因此可以算出这种情况下的最短路,对于不经过另外一部分的情况,它的最短路在这部分内,因此可以分治下去做。
考虑这个图的对偶图,它是一个每个点度数不超过 的树。通过一条对角线将其划分成两部分相当于删一条边。可以发现对于 个点的数,一定存在一种删边方式使得两部分中较小的部分点数不少于 。因此分治只会进行 层。在每一层中可以枚举每条对角线找到两部分中较小的部分点数最多的对角线。
复杂度
H. Hypercube
不会
I. Iceberg Orders
Problem
Sol
显然除去输出答案时,不同类订单之间的GP顺序不重要。
考虑维护所有订单的所有权值以及它们的GP,维护当前所有存在的订单的价格种类。对于每一类,维护这一类价格的所有订单按照GP从小到大的一个循环链表。因为每次操作的是GP最少的,操作完它又会变为GP最大的。因此匹配订单后维护GP顺序时只需要将链表头后移一位即可。
通过维护的所有价格种类,可以看成若干次一个订单和一类价格相同的订单匹配的操作。考虑一次这样的操作:
这一类订单构成的循环链表可以看成一个有向环。操作可以看成在上面依次匹配。
首先考虑在环上匹配一轮,此时如果中途订单的量已经变为 则提前结束这个过程。此时产生的交易数量的和即为最后输出的数量。因此这部分复杂度正确。
若这一轮结束后订单的量还大于 ,因为已经产生了环长数量的交易,因此可以以环长相关的复杂度处理匹配。
二分环上匹配的轮数,可以算出匹配若干轮后的交易量。因此可以求出能够完整匹配多少轮。然后再在环上匹配最后的部分即可。可以求出这样匹配完后所有GP的变化情况。
这部分的复杂度为环长乘上 ,因此设输出条数为 ,这部分复杂度不超过 。
复杂度
J. Jump
Problem
交互题。
有一个长度为 的 串 。保证 。
你可以给交互库一个长度为 的 串 ,如果 中相同的位置数量为 或 ,则交互库会返回相同的位置数量,否则交互库返回 。
你需要在不超过 次询问中求出 。
Sol
先随机询问,直到出现非零答案。这里的询问次数期望为 ,在 时期望大约为 次。此时可以找到答案或找到一个有一半位置相同的串 。
翻转 中的两个位置询问,如果返回 则说明这两个位置一个对一个错。否则说明这两个位置对错相同。
因此对于所有 都翻转 进行询问,即可求出所有位置的对错关系。此时根据 位置的正确性即可确定 ,只剩两种可能。两种各询问一次即可。
询问次数期望为
K. King’s Inspection
Problem
给一个 个点 条边的有向图,保证 。求出这张图的任意一个哈密顿回路或输出不存在哈密顿回路。
Sol
如果有解,每个点入度出度一定不为 。
考虑取一个生成树,然后通过剩余的边的端点建出虚树。可以发现虚树每条边对应的原树上的链缩起来不影响哈密顿回路。这样之后剩余的点数不超过 ,边数不超过 。
然后在图上直接dfs,复杂度
L. Landscape Improved
Problem
给一个长度为 的正整数序列 ,你可以进行不超过 次操作。
每次操作为选出一个 满足 ,然后将 加一。
求出操作后 的最大值。
Sol
考虑二分答案,设当前二分的答案为 ,只考虑 的情况,考虑枚举这个高度所在的位置 。
考虑让这个位置达到最优的最少步数的方案。此时因为需要在 位置进行操作,因此 位置的高度至少需要为 。如果 ,则需要在 位置进行操作,因此 位置的高度至少需要为 ,...
因此,考虑找到最大的 满足 。如果不存在,则上面的过程最后会推出必须在位置 操作,这显然不可能。因此这时不存在合法方案。否则,上述过程会在最大的满足条件的 处停止。这部分需要的最少操作数即为 。
对于 右侧的部分,可以类似的找到最小的 满足 。如果两侧都合法,则最少操作数为两侧的最少操作数和。
在左侧的情况中,可以发现使得一个 满足条件的 一定是一段后缀,因此可以预处理+前缀和对于每个 求出对应的 。对于右侧情况同理。
复杂度
2016-2017 ACM-ICPC Northeastern European Regional Contest
B. Binary Code
Problem
给 个由 01?
组成的串,第 个串的长度为 。每个串中最多包含一个 ?
。
你需要将所有 ?
换成 01
中的一个,使得不存在一个串是另外一个串的前缀。输出任意方案或输出无解。
Sol
每个串只有一个 ?
,因此每个串只有两种可能。
考虑 2-SAT,将所有可能出现的串插入01trie,则若一个串被选中,所有它的前缀和以它为前缀的串都不能被选中,即需要选这些串的另外一种。
因此如果将每个串对应的不选这个串(选另外一个串)对应的点放在01trie上这个串的位置处,然后对于选一个串的点向所有它的前缀和以它为前缀的串连边即可。这部分放在01trie上即为它的祖先和子树。
祖先部分和子树部分可以树上前缀和优化连边。但因为一个串不能连向自己不选对应的点,因此在01trie上的每一个位置中,这个位置上的点可以连向除了自己外其它串不选的点。对于每个点前缀和优化连边即可。
复杂度
C. Cactus Construction
Problem
给一个 个点 条边的仙人掌,你需要通过如下的操作构造出这个仙人掌:
初始有 个图,第 个图中只有一个编号为 的点。初始时每个点颜色为 ,总共有 种颜色。有三种可用操作:
- 将两个图合并,不加入新的边。
- 对于一个图,将图中所有颜色为 的点的颜色改为 。
- 对于一个图,将图中所有颜色为 的点向图中所有颜色为 的点连边。
你需要操作结束后,只剩一个图,且图中的边与仙人掌的边相同。点的颜色不做限制。
,操作次数不能超过
Sol
首先考虑一棵树的情况,注意到任意子树中只有根会向上连边,因此可以得到一个使用三种颜色的方式:
-
对于当前子树,将树根颜色改为 ,然后构造根的所有子树。
-
将所有子树和根合并,随后执行颜色 间的连边操作。因为子树中只有树根颜色为 ,这样连好了树根和所有儿子的边,因此完成了子树内连边。
-
将图内颜色 的点改为颜色 ,颜色 的点改为颜色 。此时子树中只有树根颜色为 。
考虑将这个方式扩展到仙人掌上,只需要考虑一个环的方式即可。因此可以得到如下方式:
- 考虑删去环的根(圆方树的上这个环的子树的根)后,构造环上剩余的点形成的链,再将链合并为环。
- 先使用和之前相同的方式,构造环上所有点除去环之外的子树。
- 将链的左端点染色为 ,右端点染色为 。考虑加入链的一个端点的过程,先合并图,做颜色 间的连边,然后将颜色 改为颜色 ,颜色 改为颜色 ,即可完成向链加入右端点的过程。
- 将环上其余点连成链后,合并图,做颜色 间的连边,做颜色 间的连边,将颜色 改为颜色 。此时子树内的边都完成了,且只有根的颜色为 。
复杂度 ,操作步数
D. Delight for a Cat
Problem
给定 ,有一个长度为 的序列,你需要给每个位置染红色或蓝色,使得任意一个长度为 的区间中红色不少于 个,蓝色不少于 个。
给出每个位置染红色和蓝色分别的收益,求出合法且收益最大的方案。保证存在合法方案。
Sol
记 表示 中的红色数量,相当于限制 。
看成初始时全部选蓝色,则显然将一个位置改为红色相当于将一个区间的 加一。
因此问题可以看成选一些区间,使得每个位置被覆盖的次数在一个区间之内,且选出区间的权值和最大。
考虑一个网络流模型,建 个点编号为 ,从 向 连边,费用为0。对于一个区间 ,连有向边 ,流量为1,费用为权值。流这条边看成选了这个区间。以 为原点, 为汇点,进行流量为 的网络流。此时 边的流量即为 减去位置 覆盖的次数。
因此问题可以看成所有 的边有流量上下界,求这个图的最大费用流。直接求可以通过。
G. Game on Graph
Problem
两人在一个 个点 条边的有向图上进行游戏。有一个棋子,两人轮流移动,不能动的人输。
第一个人的策略是,优先进行能让游戏无限继续的操作,其次进行能让自己获胜的操作。
第二个人的策略是,优先进行能让自己获胜的操作,其次进行能让游戏结束的操作。
双方知道对方的策略且会执行最优操作。对于每个点,求出这个点上第一个人先手/后手时游戏的结果(先手赢/输/游戏无限进行)。
Sol
将每个点分成两个点,分别代表此时第一个人/第二个人进行操作。问题变为求出每个点的胜负情况。
考虑首先求出每个点出发是否会导致无限进行,显然有:
- 如果一个点没有出边,则不会导致无限进行。
- 如果当前第一个人操作,且之后的所有状态不会导致无限进行,则不会导致无限进行。
- 如果当前第二个人操作,且之后存在一个状态不会导致无限进行,则不会导致无限进行。
- 否则从这个状态出发会导致无限进行。
初始时标记所有第一种情况的点,然后使用类似bfs的方式,维护所有当前标记了但没有更新它的入边的点,每次取一个这样的点,更新它的所有入边的点的状态,找到所有状态被改变的点。这样的复杂度为
在剩余的点进行游戏时,显然不会导致无限进行,因此不会经过会导致无限进行的点。因此可以删去所有导致无限进行的点,且之后不用考虑无限进行的情况,此时双方的策略都是希望胜利。
然后考虑对于剩余的图求出每个点出发的胜负情况。如果图无环,则可以使用同样的bfs方式求出每个点的胜负。
但如果图有环,使用bfs的方式时,可能存在部分点的胜负情况无法求出。考虑这些点上的情况,一定满足在每个点上,如果当前操作的人向胜负情况被求出的点移动,则这个人会输。因此若双方都不想输,则会在这些点上无限走。但第二个人不希望无限进行,因此他会主动输。所以对于所有没有被确定的点,它们的状态都是第一个人获胜。
复杂度
I. Indiana Jones and the Uniform Cave
Problem
交互题。
有一个 个点的有向图,每个点有 条出边。出边按照顺序排列成一个环。但不同点和边无法直接分辨。
在每个点上有一个石子,初始时石子在点的正中。在你到达一个点时,你可以将这个点上的石子放在一条出边上,且可以放到这条出边的左侧/右侧。在你进入一个点时,你可以从交互器中知道当前在正中还是在某条出边的左侧/右侧。此时从当前石子开始,按照顺时针将所有出边标号为 (在正中时随机选一个起始点)。在这个点上,你可以选择一个标号,将石子移到这个出边的左侧/右侧,再选择一个标号,沿着这条出边走。
你需要在走的边数不超过 的情况下经过所有边。保证图强连通
Sol
将石子放在出边两侧可以看成给点一个0/1的标记。
考虑使用dfs的方式遍历每个点的所有出边。将当前在dfs栈中的点标记为 ,访问过但已经不在栈中的点标记为 。对于每个点,每次走一条出边时将石子移动一位,并走现在石子所在的出边,记录走的次数即可。考虑从栈顶点走一条出边之后的情况:
- 新到达的点没有被访问过(石子在正中),则将这个点加入dfs栈顶,并将点标记为 。
- 新到达的点在dfs栈中(标记为 ),此时从这个点开始,每一步都沿着石子所在的出边走,则会形成这个点到栈顶点的的一个环。因此将此时的点标记改为 。因为环上只有这一个 ,走一次环即可知道环长。然后即可还原标记并定位到当前的栈顶。这里的移动次数不超过 。
- 新到达的点不在dfs栈中(标记为 ),考虑先找到一条路径,回到一个在dfs栈中的点,再使用上面的方式。如果能在不经过重复点的情况下回到dfs栈中的点,则移动次数也不会超过 。
考虑操作3如何进行。一个想法是在每个点上只走石子所在的出边。考虑记录从这个点出发,能走到的dfs栈中最靠前的点的深度(类似tarjan算法中的low),以及走到这个点这一步走的出边。因为图强连通,一直走low一定能回到dfs栈上。且只需要每一个点上都向low最小的出边移动。因此可以对于每个点找它low最小的出边。对于情况1,可以从子树的low转移。对于情况2,3,都可以通过循环部分的环长求出low。在一个点出边遍历结束后,将石子放到low最靠前的出边上,然后沿着石子的边走回去即可。
复杂度 ,移动次数不超过
K. Kids Designing Kids
Problem
给两个01矩阵,认为矩阵大小无限,且除去给出部分外都是 ,左上角坐标为 。保证给出矩阵不为全0。
你需要将第二个矩阵平移,使得两个矩阵将对应位置异或后的结果平移后可以等于给出的第三个矩阵。输出平移的方案或输出无解。
设矩阵大小为 ,
Sol
对于两个坐标 ,定义 当且仅当 或者 。可以发现,这样定义的为全序集,且两个点同时平移相同的向量大小关系不变。
考虑两个矩阵中的所有 位置的坐标中最小的一个,对于这两个位置:
- 如果这两个位置平移后重合,这种情况可以直接检查是否合法,复杂度 。
- 如果两个位置平移后不重合,设这两个位置为 ,不妨设 ,对于一个在 属于的矩阵中的 的位置,它现在的位置 一定满足 ,对于一个在 属于的矩阵中的 的位置,它现在的位置 一定满足 。因此平移并异或后所有可能为 的位置 都满足 。因此 一定与第三个矩阵的所有 位置的坐标中最小的一个重合。
对于第二种情况,先枚举 属于哪个矩阵,然后可以知道这个矩阵和第三个矩阵的位置关系。此时可以通过异或求出第二个矩阵,再判断是否可以平移到即可。
复杂度
L. List of Primes
Problem
考虑所有元素均为质数的所有集合,将集合按照大小为第一关键字,字典序为第二关键字排序,并按照如下方式表示:
[2], [3], [2, 3], [5], [2, 5], [7], [3, 5], [2, 7], [2, 3, 5], [3, 7], [11], [2, 3, 7], [5, 7], [2, 11], [13], [2, 5, 7],
求出这个字符串的第 个到第 个字符。
Sol
显然取前 个质数就可以构造 个集合,因此 内集合元素和的最大值不会太大。
考虑对于每个和 求出和为 的质数集合的数量,以及所有集合表示出来的长度和。这个可以直接dp求出。
此时可以发现只考虑和不超过 的集合。对于每个和分别考虑。可以发现相当于求出只考虑某个和的序列的某个区间。
设考虑的所有质数为 ,对于一个集合 ,可以将它映射到一个长为 的 01
串 ,其中第 位为 当且仅当 。
这时可以发现,对于两个和相同的集合 , 的字典序小于 的字典序当且仅当 大于 。
证明:考虑两个串第一个不同的位置 ,此时 这一位为 , 这一位为 ,但此时因为两个集合和相同,所以两个集合在这一位之后不可能没有 。因此 后面还有至少一个 ,因此将 表示成串时,前面的位相同,这一位上 是 ,而 这一位上一定大于 ,因此 的字典序小于 的字典序。
对于任意的 ,只考虑所有串的前 位,可以将所有的集合对应的串分成若干子集,不同子集之间存在字典序顺序。这时在一个区间内的集合所在的段一定是一个字典序顺序的区间。对于每一个子集,可以记录子集对应的串的前 位中所有 的位置。
时只有一个子集。考虑通过 推出 的所有与需要输出的区间有包含子集。
对于每一个子集,考虑这个子集对应的串的 位的值,可以将这个子集分成两个子集,可以得到若干个按照对应的串的字典序排序的子集,考虑计算一个子集中所有元素的表示长度和。相当于求出所有满足某些数必须在集合中, 中的数可以出现也可以不出现,且集合和为某个数 的集合的数量以及表示长度和。
考虑求出 表示 的子集中和为 的数量, 表示 的子集中和为 的所有集合的表示长度和。设必须出现的数的和为 ,则需要求的集合可以和所有 的子集中和为 的集合一一对应,且将后者的每一个集合内加入必须出现的数则为前者。因此所有集合的表示长度和可以由 表示。求出 的方式与dp相同。
因此此时可以求出每个子集元素的表示长度的和。此时可以删去两侧不会出现在输出区间中子集。通过这样的方式可以得到所有在输出区间内的质数集合。然后直接输出即可。
复杂度不超过 ,其中 为需要的质数数量。当然也可以暴力找出需要输出的集合对应串的上下界然后dfs找
M. Mole Tunnels
Problem
给出 。有一个 个点的二叉树,且点 的父亲为 。每个点有一个容量上限 。
有 个人,第 个人的位置为 ,对于每一个 ,求出:
考虑前 个人,现在每个人可以在树上沿着树边移动。需要满足移动后每个点上的人数不超过容量上限。移动方案的代价为每个点的移动距离和。你需要求出最小代价。
Sol
问题可以看成最小费用流问题。因此现在可以看成从每次操作原点向某个点加一条边,每次加边后求最小费用流。
根据费用流的性质,可以直接在上一次的残量网络上跑。考虑模拟费用流,对于每条边记录这条边的流量以及流量方向。根据费用流的方式,如果流量为 则经过这条边的代价为 ,否则与流量方向相同的边代价为 ,反向边代价为 。
对于每个点 求出 表示 子树内还有向汇点的流量的点到这个点的最短距离以及这个点的编号。每次加入一个人可以看成找一个到汇点有流量的点,使得这个人到这个点的距离最小。可以枚举两点LCA,通过 求出最短路。然后更新每条边的流量。
因为这个树每个点深度都不超过 ,因此路径长度都不会超过 。复杂度
2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest
F. The Final Level
Problem
给定 ,一个 L
型积木的形状由方格 组成。积木可以 度旋转(即选定 ,所有坐标变为 )。
你可以在网格图上放若干个这样的积木,满足积木不能重合,且只通过有积木的格子可以从格子 移动到 。输出一种放置积木数量最少的方案。
多组数据,一共有 组数据。保证所有数据的最小积木数量的和不超过
Sol
通过翻转坐标,可以只考虑 的情况。考虑问题答案的下界:
考虑横坐标的情况,这部分的下界为 ,考虑纵坐标的情况,下界为 。
考虑斜向的情况,下界为 。
此时可以发现答案即为这三个下界的 ,考虑用如下构造归纳证明:
在答案为 时,手玩可以发现一定可以构造出来,在答案大于 时:
如果 ,则可以从 向左下放一个L型到 。这时只需要用剩下的积木从原点走到 或 即可。不妨设 ,则可以贪心选择 。
如果 ,则可以从 向左下放一个中心点在左上的L型,这时积木会经过 ,剩下的只需要从原点走到 。
如果 ,则可以放一个中心点在右下的L型,类似可以发现此时接下来只需要走到 。
可以发现这样归纳 每次一定减一,因此这样的归纳可以达到最优解。又因为这样每次都是在 的左下角区域放,因此可以发现不会重叠。
复杂度 ,其中 为答案大小。
G. The Great Wall
Problem
给三个长度为 的序列 ,保证 。
给定 ,你可以选两个 内的长度为 的区间 ,满足两个区间不同。对于一种选取区间的方案,定义它的收益为每个位置的收益的和,每个位置的收益为:
如果这个位置没有被任意一个选择的区间包含,收益为 。
如果这个位置被正好一个选择的区间包含,收益为 。
如果这个位置被两个选择的区间包含,收益为 。
求出所有 种方案的收益中,第 大的收益。
Sol
考虑二分答案,变为询问收益大于某个数的方案数量。
设方案中 ,从大到小枚举 ,设 表示另外一个区间为 时的收益。考虑 时所有 的值:
将 分别减去 ,然后将 看成 ,这样只需要将最后的答案加上 的和。记 为此时 的前缀和,则:
如果两个区间相交 ( ),则
否则 ( ) ,
可以发现两个都可以分成只与 相关的部分和只与 相关的部分,因此询问 中大于某个数的数数量可以看成一个固定的序列,询问一个区间中某个值大于一个给定值的数的数量。
可以发现在 从大到小的过程中,区间端点变化的距离和为 ,因此可以看成插入删除数,询问大于某个数的数数量,可以splay/离散化BIT解决。也可以直接离线做二维偏序。
复杂度
H. Hack
Problem
交互题
固定, 考虑如下计算 的代码:
modPow(a, d, p) {
r = 1;
for (i = 0; i < 60; ++i) {
if ((d & (1 << i)) != 0) {
r = r * a % p;
}
a = a * a % p;
}
}
定义一次 a*b%p
的操作的代价为 ,其中 ,即 二进制表示的位数,其余操作没有代价。
现在你知道 但不知道 ,你可以向交互器询问一个 ,交互器会返回使用上面代码计算 的代价。你可以询问不超过 次来求出 .
的生成方式为随机两个 之间的质数 ,令 , 为在 中与 互质的数中随机选择。
Sol
对于一次询问,在不知道 的情况下也可以求出 a*a%p
部分的代价以及每一个 处的 值。可以将交互器返回的代价减去这一部分的代价。
可以发现,若看成 随机,则 和 的相差非常小,相差期望值为 。
考虑随机 ,如果存在一个 位置,使得到这个位置时 非常小,则如果 在这一位上是 ,则这次询问的值很可能小于随机询问的期望值。
进行随机询问,求出代价的平均值。然后考虑每次询问,找到让 最小的 以及剩余 的平均值。如果此时最小的 与剩余平均值的差较大且询问的代价与平均代价相差较大,则这一位很可能是 ,如果代价相差很小则这一位很可能是 。
因此可以根据 的差值和代价差值给这一位一个权值。然后对于每一位,它的权值较大意味着它是 的概率较大。在调参优秀的情况下可以直接根据权值找出答案。
但在调参不那么优秀的情况下,可以根据权值随机若干个与权值预测的结果比较接近的(例如,如果通过权值认为这一位是 的概率为 ,则随机这一位有 的概率为 ),然后验证是否符合之前的结果。这样大概率可以通过。
I. Interactive Sort
Problem
交互题。
有一个长度为 的排列,保证奇数位置上为奇数,偶数位置上为偶数。你可以向交互器给出一个奇数位置 和一个偶数位置 ,交互器会返回这两个位置的大小关系。
在不超过 次询问内求出整个排列。
保证排列随机生成。
Sol
如果只考虑奇数部分的前 个数和偶数部分的所有数,则奇数部分的数会把偶数部分的数分成 段。
考虑加入奇数部分下一个数时的操作,首先考虑找到这个数所在的段,考虑将这个数与某一段内的任意一个数比较。如果结果为小于,则这个数一定在这一段或者这一段之前,否则这个数在这一段或者这一段之后。因此可以二分找到相邻的两段,这个数一定在这两段中。
然后将这两段内的元素和这个数比较,即可划分出新的段。
考虑这样的复杂度。二分的复杂度为 ,考虑加入的元素所在的段的期望长度,即 次之前每一段长度平方和的期望。在第 次时,这可以近似看成 ,看成积分则期望为 ,这部分求和为
考虑加入元素所在段的下一段的期望长度。可以发现这个期望与上一个类似,认为 。
因此总操作次数 ,使用直接维护段或者Splay,复杂度 或
J. Journey from Petersburg to Moscow
Problem
给一个 个点 条边的带权无向图。你需要从 到 。
给定一个 ,对于你经过的路径,如果它的边数不超过 ,则你的费用为路径上所有的边的边权和。否则费用为路径上的所有经过边中边权最大的 条边的的边权和。
求出最小费用。
Sol
一定存在一个 ,满足支付的边权为经过的所有大于 的和部分等于 的。
定义一条路径在取 时的费用为,将所有边权 变为 后,路径边权和加上 的值。可以发现,对于一条路径, 这条路径在取一些 时得到的结果等于这条路径实际的费用,其余时刻得到的结果一定大于实际费用。且一定存在一个等于某个边权或者等于 的 让它取到等于。因此枚举 时只用枚举所有的边权以及 。
因此可以枚举 ,再枚举路径,计算这条路径在取 时的费用,将所有费用取 。可以发现,对于一个 ,只有此时 到 的最短路可能计入答案。因此对于每个 求出最短路即可。
复杂度
K. Knapsack Cryptosystem
Problem
给定 ,有 个正整数 ,满足 ,以及一个 满足 互质。
令 ,现在有一个长度为 的 串 ,定义
给出 ,你需要求出 。
Sol
显然可以直接折半,这样的复杂度为
在 较大时,可以发现 ,因此考虑枚举 。设 ,其中 为奇数,则因为 为奇数,显然有 ,并且因为 ,可以确定 二进制的后 位。
此时每一个 可能的 有 个,可能的 有 个,因此考虑枚举所有的 以及 的前 位,此时有 种情况,对于每一种 的情况,可以直接求出 判断是否满足要求。复杂度 ,但因为在随机 的情况下,还原 时出现 的期望时间为 ,因此复杂度期望为
复杂度
L. Laminar Family
Problem
给一棵 个点的树,现在有 个集合。对于每个集合,给出 ,表示这个集合为路径 上的所有点构成的集合。
求出对于给定的这些集合,是否满足:
对于任意两个给出的集合 ,都满足 或 或
Sol
按照集合大小排序,则可以看成要求对于每一个集合,在它之后且与它相交的集合必须包含它。
考虑如下做法:
从后往前考虑每个集合,对每个元素维护一个标记。加入一个集合时,满足条件当且仅当这个集合中所有元素的标记相同。然后对于集合中的每个元素的标记中加入这个集合对应的编号。
显然满足条件当且仅当上面的过程会得到满足条件的结果。
标记显然不能直接维护,考虑,将每个标记看成一个数,给每个集合一个 级别的数,然后给一个元素标记看成将这个标记异或集合对应的数。此时可以发现把不等判断成判断相等的概率为 ,因为判断错误当且仅当每一次不等都被判断为相等,因此最后判断错误的概率不超过 。
因此问题变为链异或,求一条链点权是否全部相等。可以直接树剖解决。
复杂度
2014 ACM-ICPC World Finals
A. Baggage
Problem
个物品排成一列,每个物品可能是 A,B
两种类型之一,初始时所有物品排成 BABABABA...BA
的形状,物品左侧有 个可用的空位,物品初始坐在的位置编号为 ,空位编号为
你每次可以选择两个相邻且都有物品的位置,拿出这两个物品,在不改变它们顺序的情况下把它们放到任意两个连续且空的位置中。
你需要使用最少的操作,把物品变为 ...AAAA...ABBBB...B...
,对物品两侧的空位数不做要求。输出方案。
Sol
手玩可以发现这样的方式:
__BABABA....BABABABA
ABBABABA....BABAB__A
ABBA__BA....BABABBAA
(中间部分递归操作)
ABBAAAAA....BB__BBAA
A__AAAAA....BBBBBBAA
AAAAAAAA....BBBBBBBB
此时可以通过 步,把 的问题变为 的问题。
同样手玩可得,对于 存在 步方案,但不存在只使用左侧两空位的方案。对于 都存在 步只使用左侧两空位变为 AA..ABB..B__
的方案。
此时通过递归即可得到 步的做法。
考虑计算不考虑空位时相邻且不同的字符对数。可以发现初始这个值为 ,结束时为 ,可以发现每次操作这个值最多 。
又因为显然第一次操作这个值最多 ,因此操作步数至少为 。因此直接这样构造即可。
复杂度
B. Buffed Buffet
Problem
你想买质量为 的物品,一共有 种物品,每种物品数量无限。物品分为两类:
- “离散的” 物品,这种物品只能取整数个,一个物品有质量 以及 ,代表选这种物品 个的收益为
- “连续的” 物品,这种物品可以取任意实数质量,一种物品有两个值 ,代表选质量为 的这种物品的收益为
求出买质量正好为 的物品时的最大收益,或者判断无解。
,所有数为非负整数。
Sol
首先考虑只有第一类的情况,考虑dp,设 表示考虑前 种第一类的物品后重量和为 的最大收益。
考虑加入一个物品时的转移,将dp按照 分类,对于每一类,dp为:
可以看出这是斜率优化的形式,直接做就行。
这部分复杂度为
考虑加入第二类,枚举第一类的重量,问题变为询问使用第二类物品和为 的最大收益。
如果将一个物品选的数量和收益看成函数的关系,则可以发现得到的都是上凸函数。
此时可以发现,在最优解中,对于一个选择量大于 的物品 和一个物品 , 的函数在选择量处的导数必须不小于 的函数在选择量处的导数。否则调整减小 增加 可以更优。
因此在最优解中,所有选择量大于 的物品 , 的函数在选择量处的导数都相同,且选择量等于 的函数在 点的导数都小于等于这个导数。
因此可以二分导数,找到选的数量正好是 的导数,也可以按照 排序后扫过去。
复杂度 或者
C. Crane Balancing
Problem
有一个 个点的多边形立在地平线 上,多边形的质量均匀,且每 单位面积的质量为 。
称多边形平衡当且仅当它能在当前位置稳定,不向某个方向倾斜。
现在在某个点上有一个物品,物品的质量为 。求出能使多边形平衡的 的区间。
Sol
考虑没有物品时多边形能不能平衡。考虑多边形与地面相交的区间,可以发现,如果多边形的重心横坐标在这个区间内,则向一侧端点旋转重心高度都会变大,因此此时是稳定的。
否则,沿着一侧端点那一侧旋转会使重心高度变小,此时一定不稳定。因此只需要使重心横坐标在这个区间中即可。
考虑求出多边形重心,可以将多边形划分成 个有向三角形。对于每个三角形,它的重心坐标是三个顶点坐标的平均值。此时问题变为有 个点,每个点有坐标和质量,求出重心。
可以发现,此时求这些点坐标的带权平均即可。
求出重心之后,加入物品相当于再加一个点,可以根据这个点横坐标,重心横坐标直接求出这个点合法的质量区间。
复杂度
E. Maze Reduction
Problem
有一个 个点,无自环无重边的无向图。点 有 条出边,出边按照给定顺序排成一个圆。
你会从某个点开始在图中游走。所有的点和边间不可区分。当你到达某个点时,你知道的信息只有这个点的出边数量以及你走到这个点时的这条边的位置。因为边不可区分,你能进行的操作只有选择一个 ,走从进入这个点的边开始,顺时针第 条边。
定义两个点 是等价的,当且仅当你从其中一个点开始走,不能分辨出自己的出发点是 还是 。
可以发现,可以将所有点划分成若干个集合,满足同一个集合中的两个点之间等价,不同集合中的两个点不等价。求出这样的集合划分。
Sol
因为能在 步之内走到一个点,因此如果两个点不等价,则走 步之内一定可以找到不同。 因此两个点等价当且仅当 步以内每一种走的方案(每一次选的 )得到的路径上每个点度数相同。
考虑hash,设 表示当前从 走到 ,之后再走 步的所有路径的hash值。
考虑这一步的情况,设 的出边为 ,其中 ,则根据这一次选的 从小到大,接下来的状态为 。将这个看成一个序列,求序列再加上当前点度数的hash值即可。
对于起始点的情况,因为没有入边,因此所有的状态会排成一个环。可以选择一个字典序最小的断环为链的方式,然后做hash。这样得到了每个点出发的所有路径的hash值。
可以发现,如果两个点等价,则它们的hash值相同。因此取 级别的模数做hash即可使正确概率足够大。
复杂度
F. Messenger
Problem
有两个人在一个二维平面上,两个人分别有一个由 个点组成的路径。在初始时,每个人位于自己路径的起点,随后,每个人会从当前点开始,沿着最短路径走到自己路径的下一个点。两人的速度都是 。
第一个人有一个物品,他要把这个物品给第二个人。第一个人可以在到达终点的那一刻以及之前将物品传递出。随后,物品会沿着某个方向,以 的速度移动。如果在第二个人到达终点的那一刻或者之前他的位置与物品重叠,则他可以拿到物品。
两个人和物品都不能停下,求出在成功传递物品的情况下,物品从被传递出到被拿到中间移动的最小距离。输出最小距离或者无解。
,两条路径长度不超过
Sol
假设固定了起点 ,考虑终点的位置 ,这个位置需要满足第一个人到 的时间加上 等于第二个人到 的时间。
考虑将 向第二个人到 的距离更小的方向移动。假设移动的距离为 ,则根据三角形不等式 。因此向这个方向移动时,第二个人会比物品更先到达 。如果向另一个方向移动,则物品会先到达。
可以发现如果 取起点,则一定第二个人先到达。因此如果 取第二个人终点时仍然 先到则无解,否则可以二分这个位置。
可以发现固定 的情况类似。因此在 从第一个人起点开始向前移动时, 也在向前移动。
考虑将合法的 取值划分成若干个区间,满足每个区间内 在一条线段中,且对应的 也在一条线段中。
对于每一个 的路径顶点,二分出它对应的 位置,按照这些位置加上 的所有顶点划分,得到的这些区间就满足条件。
现在考虑一个区间,它满足 在一条线段中,且对应的 也在一条线段中。
此时可以发现,随着 变化,答案会是一个单峰函数。因此在每一段上三分 ,再二分 即可。
复杂度
G. Metal Processing Plant
Problem
给一个 个点的完全图,每条边有边权 。
你需要将 个点划分成两个集合 。定义 ,你需要最小化
输出最小值。
Sol
n^4/64是啥震撼东西
考虑钦定第一个集合的 不超过 ,第二个集合的 不超过 。考虑判断这个是否合法。
可以发现这能够 2-SAT,大力建边即可。这样单次复杂度 。
考虑设 ,那么可以发现,所有边权大于 的边,在 2-SAT 中相当于要求两个点状态不同。对于一个 ,显然可以二分求出最小的合法 。这样单次
可以发现,在一个连通块中加入一条不带来奇环的这样的边和不加入是等价的。因此,在 从大到小的过程中,只考虑边权大于 的边,只有当新增加的一条这样的边连接了两个不同的连通块或者连出奇环(出现这种情况则更小的 都无解)时,这部分边的效果会发生变化。这样的情况只有 次。
因此,只需要在每次连通块变化前的 做二分,复杂度 。
但注意到,上面条件成立的前提是 ,但可能出现在上一次变化时的结果是 ,但这一次变成了 ,此时需要在这一段中二分找到最后一个 的位置。
复杂度
H. Pachinko
Problem
有一个 行 列的网格,有一些位置是障碍,一些位置是终点,第一行没有终点。
一个小球从第一行的随机一个非障碍位置开始移动。给出小球每一步向上/下/左/右的概率,小球每一步都会按照这个概率选一个方向移动,如果移动后的位置是障碍或者出界则不移动。
当小球到达某个终点时,小球停止。
求出小球停在每个终点的概率。
Sol
考虑设 表示小球经过位置 的次数。可以发现, 只和它四周的格子相关。
考虑对第一行进行消元,可以发现,消元后,一定可以将 用第二行的 表示出来,即表示成 的形式。
使用同样的方式,可以依次对每一行消元,最后可以通过最后一行求出这一行的 ,再反向推出所有 即可。
没写过不知道细节多不多
复杂度
I. Sensor Network
Problem
给二维平面上 个点以及一个 ,两点之间有边当且仅当两点距离不超过 。求出图的最大团。
Sol
直接随机就能AC
考虑枚举最大团中距离最大的一对点 ,考虑剩余点的情况:
此时剩余点一定在 为圆心,半径为 的圆和 为圆心,半径为 的圆的交中,即图中 区域。
此时相当于在这个区域内选出若干个点,满足两点距离不超过 。可以发现,此时如果将区域沿着 分开,则上面区域中的任意两个点都满足条件,下面区域中的任意两个点都满足条件。
因此只有一个上面的点和一个下面的点可能不满足条件,因此这部分相当于在一个二分图中选最大独立集。直接网络流即可。
复杂度 ,跑不满
J. Skiing
不会
K. Surveillance
Problem
有一个长度 的环,给出 个区间,选出个数最少的区间,使得环上每个点都被某个选择的区间覆盖。
输出最小个数或输出无解。
Sol
考虑链上的情况,设当前覆盖了长度为 的前缀,则下一步一定是贪心找左端点小于等于 的区间中右端点最大的 ,然后选这个区间,将当前覆盖的前缀长度设为 即可。
对于环上的情况,考虑枚举选择的一段,如果一段被另外一段完全包含,则选这一段一定不优。因此选了这一段后将环分开,剩余的每个区间在链上还是一个区间,这样变成了链上的问题。
注意到链上每一步操作都是找包含 的区间中右端点最大的区间,可以在环上预处理这个东西。这样可以得到每个 下一步的 。然后对这个东西倍增即可在 的复杂度内求出一个链上的问题。枚举一段直接做即可。
复杂度
L. Wire Crossing
Problem
在二维平面上有 条线段,线段不会重叠但可以相交。
给定起点和终点,你需要找一条从起点到终点的路径满足:
- 路径不经过已有线段的交点
- 路径与线段相交的次数最小
求出最小相交次数。
Sol
考虑建这 条线段对应的平面图,先枚举每一对线段,找到所有的交点。对于每条线段,找到它依次经过的所有交点,将相邻交点连边。这样就得到了线段对应的平面图的所有边。
然后考虑建对偶图,对于每个点将它的出边极角排序。考虑从一条边的某一侧开始走,找到一个区域的边界。在到达一个点时,走到对应方向极角排序后下一个出边即可。走回初始位置时即找到了这个区域的边界。
这样可以对于一个平面图上的连通块找到这个连通块内所有区域的边界,以及连通块的外边界。考虑对于每个外边界找到这个外边界属于的平面区域。在外边界中选择一个点,判断这个点属于哪个平面区域即可。这里需要极其注意出现多边形内切以及内切共边的情况。
在得到了上面的东西后,即可对于平面图建对偶图,答案显然是对偶图上两点最短路。
复杂度
2015 ACM-ICPC World Finals
B. Asteroids
不会
E. Evolution in Parallel
Problem
给出 个字符串 以及字符串 ,你需要将这 个字符串划分成两个序列,满足:
- 对于每个序列中相邻的两个字符串,前者是后者的非平凡子序列。
- 每个序列中最后的字符串是 的非平凡子序列。
定义 是 的非平凡子序列当且仅当 是 的子序列且
Sol
如果有一个字符串不是 的子串显然无解,否则一定不需要考虑 。
考虑将字符串按照长度排序,显然最后的序列一定是排序后的顺序子序列。
因此可以设 表示考虑前 个串,当前第一个序列的结尾为第 个串,第二个序列的结尾为第 个串 (),这种情况是否合法。但因为转移复杂度为 ,因此这样无法接受。
考虑找到最小的 ,满足 这一段放在一个序列中合法。因为 不能再放入,因此此时如果第一个序列的结尾为第 个串,则第二个序列的结尾一定不会小于 。
然后考虑第二个串结尾在 内的所有状态。因为这部分内前一个都是后一个的子序列,因此显然第二个串结尾越靠前越优秀。因此这部分只需要记录最小的一个。
因此,对于每个 ,只需要记录最小的两个满足 合法的 进行转移即可。这样转移次数只有 。
复杂度
G. Pipe Stream
Problem
有一个长度为 的管道,一个物品从管道一侧开始向另外一侧移动,它的速度 位于 之间。
你想知道这个物品的速度。你可以在某个时刻选择一个管道上的一个位置 ,你可以知道当前物品是否已经经过了 。称这样的操作为观察操作。
观察操作的频率存在限制。你只能在物品开始运动 秒后进行第一次观察操作,且两次观察操作间的间隔不少于 秒。
你希望求出一个物品的速度 ,满足 ,其中 给定。
你需要找到一个策略,使得你一定能找到满足条件的 且在最坏情况下,你观察的次数最小。
输出最坏情况下最小的观察次数或者输出无解。
多组数据
,所有数都是整数
Sol
可以发现,在时刻 观察位置 相当于判断速度是否超过
因为可以观察任意位置,这相当于在 中选一个值,判断速度是否超过这个值。
因此每次 选的尽量小最好,所以每次操作的时刻一定是
考虑一种操作策略。显然操作策略可以被描述为一棵树的形式:
根节点对应区间 ,随后在这个区间内选择一点 ,判断当前的速度是否超过 ,随后若没有超过,则只需要判断 ,否则判断 ,因此可以将这两个区间看成两个儿子。
因为要求差不超过 ,因此如果当前需要判断的区间长度小于等于 ,则可以结束这个过程。称这样的区间为结束区间。
考虑每个点,设它的深度为 ,则到这个点时是第 次操作,因此此时选的的 不能超过 ,且只要满足这个条件一定合法。
可以发现, 变小一定不会使得操作树不合法。因此如果存在除去第一个以外的一个结束区间长度不为 ,则将这个区间长度向左增加到 ,左侧所有端点相应左移。此时一定不会变差。因此存在一种最优方式,满足除去第一个区间外,每个结束区间长度都是 。
此时可以发现,所有询问的位置即为 。考虑求出对于每个位置,它只能在前多少次操作被选,记这个次数为 。
考虑判断是否合法,可以看成如下问题:
有一个序列 ,你每次可以选择一个大于 的位置,将其删去,剩余的每个数减一。
如果删完序列为空则你获胜,否则你获胜当且仅当对于分出的两部分你都能获胜。
求你能不能获胜。
直接做没有较优做法,但可以发现,因为 ,可以发现序列不增。 此时可以发现如下性质:
序列单调时,序列 有解当且仅当
考虑对序列长度归纳,序列长度为 时显然有解当且仅当 ,即 。
设序列长度为 ,若 ,考虑从右向左,找到第一个位置 满足 。
此时,。在从 位置分开后,两侧和小于 ,全部减一后满足和小于 ,根据归纳有解。
如果 ,同样考虑找到这样的 。
此时因为 ,有
因为 ,因此两侧都是整数,因此右侧等号成立,所以
可以发现,此时从 中间分开,右侧和等于 ,左侧和大于等于 ,因此删一个位置后一定有一侧和大于等于 ,全部减一后和大于等于 。
因此归纳成立。
此时即可判断是否有解,考虑计算最优解。
二分答案,考虑答案为 是否合法。可以发现,如果存在一个解,则此时把所有大于 的 变成 不影响这个解是否合法。
因此,考虑把序列每个元素 变成 ,显然如果此时有解,则存在一个最差步数小于等于 的解。因此可以用和之前一样的方式判断合法。
最后考虑求出 。因为 ,根据数论分块的结论,不同的 只有 个。使用类似数论分块的做法,即可求出每一种出现的 以及每种 出现的次数。
考虑计算 ,相当于有 对 ,求 。只需要做类似二进制下的竖式加法即可。这样的复杂度为
再加上二分答案即可,复杂度 。因为答案上界实际上很小,复杂度不满。
H. Qanat
Problem
给出 ,考虑一个直角三角形形状的山峰。三角形由 三点构成。保证
给出 ,你需要选出 个位置 ,然后:
你需要在山峰中挖掘从 到 的路径,从 到 的路径,以及对于每个 ,从 到 的路径。
挖掘一个点的代价 为只使用挖掘的路径,到达山峰表面(即 这些点)的最短距离。挖掘的总代价即为
你需要找到一个方案,使得总代价最小。输出最小代价以及方案。
Sol
考虑点 的最短距离。显然走到 需要 的距离,走右侧的点显然不优。
考虑走左侧的点 ,此时距离为 。因为 ,因此这也是不优的。
因此每个 一定走到 最优。可以发现,此时对于 最近的点一定是 。对于 到 这一段最近的点一定是 或者 。
考虑每一段挖掘的代价。对于竖直线段,因为它最近的一定是到正上面,因此这部分的代价为
然后考虑横向 到 的一段。考虑 的折线,可以发现只考虑这条折线内,每个点的 和整体的 相同。对于这条折线,最优解显然是从中间分开,向两侧移动。设折线长度为 ,则代价为 。
因此这条折线的代价为 ,因此总的代价为:
考虑一组最优解,显然在最优解中,对于每一个 ,只将 看成变量,得到的函数在此点导数必定为 。
因此此时有:
考虑满足所有这些限制的 ,设 ,则可以用 表示出所有 ,再通过 即可求出 。
因此可以发现满足这些限制的 唯一,因此这即为最优解。
复杂度
J. Tile Cutting
Problem
对于一个 的长方形,左下角坐标为 ,在长方形的每条边上选一个点,满足:
- 每个点都是格点,且不能选长方形的顶点。
- 这四个点构成一个平行四边形。
记 为使用这种方式,能构造出来的形状不同(旋转/翻转后相同算不同)的面积为 的平行四边形个数。
组询问,每次给 ,求出 以及取到最大的 。
Sol
考虑把原点设在左侧选的点,设此时上侧选的点位置为 ,下侧选的点位置为 ,显然
此时显然另外一个点位置为 ,且显然这样的平行四边形能被切出来。
可以发现,只要 不同,得到的平行四边形形状一定不同。对于一组 ,计算叉积可以发现平行四边形的面积为 。
因此 相当于满足 的正整数 对数。记 表示满足 的正整数对数,可以发现 。
求 可以线性筛,然后FFT求 即可。
因为询问次数很少,询问可以直接暴力。
复杂度
K. Tours
Problem
给一个 个点 条边的图,定义一个正整数 是合法的,当且仅当:
存在一种给每条边染 中颜色的方案,使得图中的每一个简单环上 中每种颜色出现次数相同。
求出所有合法的 。
Sol
之前的做法是假的,重新编了一个.jpg
所有的 度点显然没用,可以删去,然后可以一直删直到没有 度点。
此时考虑再把 度点缩成一条链,考虑一条链的情况。
对于一条链 ,如果删去它后它的两个端点 在同一个点双内,则相当于这两个端点在一个简单环内。
设简单环为 ,则考虑环 ,通过前两个环相加再减去第三个环,可以得到 这条链上所有染色出现次数必须相同。
因此合法的 一定是 链长的约数。可以发现如果将这条链的端点合并后求出所有答案,答案加上这条链带来的限制一定是整体的答案。
因此只需要每次找到一条这样的链即可。显然可以做到线性。总复杂度
细节咕咕咕了。
L. Weather Report
Problem
给出 。有一个长度是 的字符串,其中每一位为 的概率为 ,...,为 的概率为 。
你需要对 种可能出现的字符串中的每一个进行编码。每个字符串对应一个 串。这些编码需要满足不存在两个 串满足一个是另外一个的前缀。
定义编码方式的代价为每种字符串出现概率乘上它对应的编码长度的和。求出所有方式中最小的代价。
Sol
可以发现这是Huffman编码的形式,把概率看为权值即可。
显然,一个字符串出现的概率只和每种字符出现的次数有关。因此枚举每种字符出现的次数,可以得到 种概率,以及每种概率的字符串数。
考虑Huffman编码的正常做法,每次拿出两个权值最小的,将它们加起来,代价加上它们的和。对于多个相同的值,它们的操作显然可以一起做。
若干个相同的数在 轮合并后就会变成 个数,可以发现只会有 次这样的操作。
显然合并出来的数权值递增。可以将原先的数排序后放在第一个队列,合并出来的数放在第二个队列,每次拿出两边较小的队首即可。
复杂度
M. Window Manager
Problem
给一个 的二维平面,支持 次如下操作:
- 向平面中加入一个矩形。矩形的边界平行于整体边界。如果加入矩形会导致矩形重合或出界,则不加入并输出错误信息。
- 选择一个位置,删除包含这个位置的矩形,不存在输出错误信息。
- 选择一个位置,改变包含这个位置的矩形的大小,如果不存在或者改变后导致矩形重合或出界则分别输出错误信息。
- 选择一个矩形,将其向四个方向中的一个移动一个距离。矩形移动的过程中如果遇到其他矩形,则会推动这个矩形继续移动。不能移动则停止。如果移动的距离小于目标距离,则输出错误信息。
最后输出此时的所有矩形位置。
Sol
前三个操作暴力判断即可,考虑最后一个操作。
假设当前为向右推,记 表示矩形 最后的左边界位置。
则如果矩形 在矩形 的左侧且矩形 向右能碰到矩形 ,则设矩形 的宽度为 ,则无论怎么向右推都有 。
对于推动的操作,先考虑无视边界的限制,则操作为将 加 ,随后通过上面的不等式更新所有点的 。可以发现这样得到的结果即为正确的结果。
可以发现上面的不等式相当于图上的单源最长路。可以 求出。
此时可以求出超过边界的距离,然后少推这么多距离即可。
复杂度 ,注意细节。
2016 ACM-ICPC World Finals
A. Balanced Diet
Problem
有 种物品,每一天,你可以选择拿任意一种物品中的一个。
设 表示前 天拿走的第 种物品的数量,给出 ,定义 ,你的方案需要满足:
现在给出前 天你的选择,保证这部分合法,之后你可以任意选择,你可以在任一时刻停止。你希望你之后额外选择的次数最多。
输出你最多还能选多少次,如果可以无限选输出 forever
。
Sol
如果只考虑下界,则相当于如下问题:
每种物品在 轮之前是合法的,每次选择它会让它的合法轮数加上 。
此时显然的贪心做法是每次选一个合法轮数最小的加。相当于每次选一个 最小的加。
显然,在 轮后,,因此一定存在一个
此时选的数一定满足这个限制,此时再选一个这个,则 ,因此这样选一定满足上界。
同时 轮后显然所有 的差不超过 ,此时再做 轮一定循环。因此这么多轮之后如果还合法则表示一定可以无限进行下去。
复杂度
B. Branch Assignment
Problem
有一个 个点 条边的有权连通图,上面有 个人,给出每个人的位置。
对于前 个人,记人 到人 的距离为 。
你需要将所有人划分成 个集合,对于一个集合 ,它的代价为:
总的代价即为每个集合代价之和。求最小的总代价。
Sol
考虑给代价加上 ,可以发现这时一个集合的代价变为 。
假设确定了最后集合的大小,则显然是把 小的往 大的放。因此存在一种最优方式使得集合的划分方式等价于将所有 排序,然后在序列上划分出若干段作为若干个集合。
此时可以设 表示前 个元素划分 段的最小代价,转移为:
可以发现转移系数显然满足四边形不等式,因此每一层的转移有决策单调性,直接dp即可。
复杂度
D. Clock Breaking
Problem
有一个显示时间(小时/分钟)的电子表,电子表为一个 的区域,其中有 个部分显示时间。
但是这些部分可能存在问题,一些部分可能永远不会亮,另外一些部分可能永远都亮。
给出连续 分钟中每一分钟它的显示情况,判断每个部分的状态(正常工作/常暗/常亮/无法确定)。如果无解输出 impossible
Sol
考虑枚举一个开始时间,判断是否可能是这个开始时间,此时满足如下条件:
对于一个部分,它在这个区间中满足以下两者之一:
- 这部分给出的显示情况和这部分正常情况下的显示情况匹配。
- 这部分在给出的显示中常暗或常亮。
判断第二个非常容易,对于第一个,可以使用bitset优化判断。
如果得到一个开始时间合法,则显然可以求出此时每个位置可能的状态。枚举所有时间即可得到最后每条线段可能的状态集合,即可判断答案。
复杂度 好像没有必要bitset
F. Longest Rivers
Problem
有一个 个叶子的树,满足每个点的儿子数量不为 。每条边有长度。
从每个叶子开始都有一条河流出发。当多台条河流相遇时,一条河流继续延伸,其它一条河流在此停止。
定义一条河流的排名为长度大于它的长度的河流数量加一。对于每条河流,求出它对于所有延伸的情况,它的最小排名。
Sol
考虑一条河流的答案,最优情况下然这条河流会延伸到根,此时相当于需要长度大于这条河流的河流最少。
从下往上考虑,对于每个点,如果子树内还没有长度大于给定值的,则显然希望让长度最小的向上延伸最优。
但如果长度最小的加上向上的边后大于给定值,则此时经过这个点向父亲边的河流长度一定大于 。
考虑所有满足这个条件的边,经过这些边的河流长度都大于 。可以发现,设 为这些边中满足子树内没有这样的边的边数量,则显然至少需要 条河流覆盖这些位置,且这 条河流可以覆盖这些边到根的路径。因为询问点到根的距离为给定值,因此询问点到根路径上的边不会出现,因此 即为答案。
可以发现一条边是否满足条件只与子树内叶子到它的最小距离是否大于给定值有关,按照给定值排序后相当于如下操作:
- 加入一条边。
- 询问当前有多少条边满足它的子树内没有被加入的边。
数据结构维护当前每个子树被哪条边覆盖,这样加边的时候就能找到变成不满足条件的边。
复杂度
H. Polygonal Puzzle
不会
I. Road Times
Problem
给一个 个点 条边的有向图,边有长度。
在每条边上还有一个 之间的实数因子,经过这条边的时间为长度乘上这个因子的乘积。
给出 ,已知 条如下信息:
一个人从 出发到 ,他一定会选择长度和最短的方案。已知他经过这部分用了 的时间。
有 次询问,每次给出 ,表示:
一个人从 出发到 ,他一定会选择长度和最短的方案。你需要求出他需要时间的上下界。
,边权不超过 ,保证给出的 对点间最短路唯一。
Sol
记每条边的额外权值为一个 间的实数变量 ,则可以看成如下约束:
- 对于一个给出的路径 ,
- 对于询问的路径 ,最大/最小化
那么可以对于每个询问跑单纯形即可,复杂度 。
可能需要用力卡常,一种有效的方式是先初始化再跑每组询问。
J. Spin Doctor
Problem
给出 对数 ,其中有一些数对为关键的数对。
你需要选择实数对 ,随后将所有的数对按照 排序,定义此时的权值为最坏情况下排序后关键数对间距离的最大值。
你希望权值最小,输出最小的可能权值。
Sol
特判只有一个关键点的情况,此时答案一定为 ,否则选择 后,设关键点的 的最小值,最大值为 ,则最坏距离一定为 。
将数对看成二维平面上的点,可以发现选择 相当于选择一个斜率,用两条这个斜率的线去夹所有黑点。这些相当于夹所有关键点的凸包。
求出关键点的凸包,则相当于找到一对平行线夹这个凸包,使得平行线夹住的点数量最小。
考虑平行线角度旋转的过程。对于凸包内的点,它一定全程在平行线内。因为得到的都是凸包的切线,对于一个凸包外的点,考虑求出它到凸包的两条切线。可以发现,在旋转的过程中,这个点在平行线内的时间段一定是从碰到一条切线开始,到碰到另外一条切线结束。
只需要求出切线,即可求出这个点在平行线内的时间段。这样通过旋转即可求出所有情况的最小答案。
在凸包上选一个点,考虑这个点和凸包上点的连线,可以二分求出这条线和凸包另外一个点的交点。
然后只需要在两侧分别找到两个方向上最外侧的点,可以发现这个过程类似于凸包上二分,判断凸包上相邻两条边以及这个点的连线的角度关系即可。
复杂度
K. String Theory
Problem
称一个串为 层嵌套串,当且仅当这个串的开头结尾为引号 '
,且其他字符都不是引号。
称一个串为 层嵌套串,当且仅当这个串的开头结尾都有 个引号,且删去这 对引号后,剩下的部分由若干个 层嵌套串和若干非引号字符组成。
给出 以及 个正整数 ,一个串的组成方式为 个引号加上若干个非引号,加上 个引号加上若干个非引号,...,加上 个引号。求出最大的 ,满足这个串是 层嵌套串。
Sol
考虑判断一个串是不是 层嵌套串。一个显然的条件为引号数量为偶数。
如果 ,则合法当且仅当原串只有两个引号。
如果 ,可以发现只要前两个引号连续且后两个引号连续,中间的引号可以全部看成 层嵌套串。
对于 的情况,显然开头结尾都必定顺序出现 个连续引号。如果不能将开头结尾划分成这种形式则无解。
可以发现,此时可以把中间的引号全部看成 层嵌套串,这样得到的一定为一种合法 层嵌套串。因此满足上一个条件一定合法。直接判断即可。
复杂度
M. What Really Happened on Mars?
Problem
模拟一个优先级上限协议
Sol
考虑直接模拟执行的过程,记录当前每个任务执行的情况以及当前每个资源被锁定的情况。唯一的问题在于每次计算当前优先级和阻塞关系。
每个资源的优先级上限已经确定,因为一个任务的当前优先级为所有被它阻塞的任务的优先级的最大值,考虑从高到低枚举优先级,判断哪些任务的优先级等于这个优先级。
考虑基准优先级等于当前枚举的优先级的任务,如果它的当前优先级已经确定(大于基准优先级),则这种优先级一定在当前优先级中不会出现。
否则,因为剩下没有被确定的任务优先级一定小于等于它的优先级,因此这个任务的当前优先级等于它的基准优先级。
此时可以求出这个任务被哪些任务阻塞,如果阻塞这个任务的任务 的当前优先级已经确定(大于它的当前优先级),则这个任务的当前优先级不会改变。否则,任务 的当前优先级会变的和这个任务的当前优先级一样。可以发现它的当前优先级也被固定了。可以使用类似bfs的方式实现这个过程。此时没有被确定的点当前优先级一定小于此时的优先级。
在上面的过程中每个点只会被确定一次,因此复杂度显然为
注意到只要不出现新加入任务的情况,如果当前执行的任务执行到了若干个连续的 C
,则显然之后的时刻所有优先级不变,直到这连续的 C
被执行完。因此总的模拟步数为
复杂度
2017 ACM-ICPC World Finals
A. Airport Construction
Problem
给一个 个点的简单多边形,你需要在多边形内部画一条线段,求线段的最长长度。
Sol
显然可以通过平移线段,使得线段至少覆盖一个顶点。
然后以这个点为原点旋转线段,考虑线段长度的变化,相当于以某个方向向双向连出射线,在第一个出界的位置停止。可以发现,一个端点在多边形的一条边上移动时,这一侧长度的变化为一个下凸函数。而凸函数改变的时刻即为碰到一个顶点时。
两个下凸函数相加还是下凸函数,可以发现对于下凸函数一定在端点处取值最优。因此最优解一定至少经过两个多边形顶点。
考虑枚举两个多边形顶点,考虑它们的连线,然后求出此时延伸的长度。枚举每条多边形的边判断相交即可。注意出现重合等特殊情况。
复杂度
B. Get a Clue!
Problem
Sol
可以发现,每一种可能的信息(没有反驳,进行了反驳)相当于对一个人手上的牌进行了限制。
除去第一个人的牌后,剩余牌只有 张,考虑枚举一个人手上的牌,判断是否合法。此时只需要满足如下条件:
对于一次提议,如果问到了这个人且这个人没有反驳,则这个人一定没有这三种牌。
如果这个人反驳了,则这个人一定至少有这三种牌中的一张,如果证据可见则一定他有这一张。
因此可以 求出每个人可能的牌集合。显然最后只需要知道所有人的牌的集合,考虑合并每个人的牌。
因为每个人的牌数量固定,因此可以直接看成一个与卷积。最后枚举判断即可。
复杂度
D. Money for Nothing
Problem
给出 对 , 对 ,你需要在两侧各选一对,最大化:
Sol
看成二维平面上的问题,则相当于有若干个黑白点,你需要选一个黑点作为左下角,一个白点作为右上角,最大化这样得到的矩形的大小。
可以发现如果一个黑点 在另外一个黑点 的右上方,则 被 替代一定更优。因此可以删掉没用的黑点。最后剩下的黑点 按照 排序后满足 。白点同理。
此时如果一个留下的白点在留下的黑点的左下方,可以发现这个白点一定没有意义,可以直接删去。
此时设 ,则留下的点中计算这个值与计算原答案等价。问题变为求 使得 最大化。
可以发现这个满足 ,即满足决策单调性。因此可以直接分治。
复杂度
G. Replicate Replicate Rfplicbte
Problem
有一个无限大的01矩阵 。有一个 的初始矩阵 。在时刻 时,矩阵 中的一个 的区域的值等于 ,其余区域均为 。
在每个时刻中, 的每个位置上的值都会发生变化。对于一个位置,这个位置的值为上一个时刻这个位置周围的 个位置的和模 的结果。
但在每一个时刻的变化后,可能会有一个位置上的值发生变化( 变 , 变 )。
在若干个时刻后 矩阵中所有的 在一个 的区域中,给出这个区域中每个位置的值,你需要找到一个大小最小的初始矩阵 ,使得矩阵 能通过上面的变化能变为 。
Sol
称当前矩阵的外边界为一个最小的包含矩阵所有 的矩形。
可以发现,假设之前的外边界为 ,则一次变化后外边界一定会扩展一圈,即变为 。并且显然这之后再改变一个位置的值不能改变外边界大小。
考虑倒推每次操作之前的情况,可以发现每倒推一次外边界必须缩小一圈。
如果没有翻转一个格子的值的操作,则每个位置现在的值是之前周围 的值的异或和。在这一次之前,外边界上的位置应该全是 。考虑从上往下依次确定每个位置之前的值,可以通过 现在的值以及 之前的值推出 之前的值。
但如果翻转了一个格子,会导致这样求出的结果在下右边界上不是全 。考虑翻转 ,可以发现,这会改变所有满足 $x\leq x',y\leq y',3\not\equiv(x-x')(y-y') $ 的点 的值。
因此考虑推出下右边界上两行的值,通过这两行上推出的值,可以找到唯一一个能让边界变为 的 。
因此这一步可能的改变一个位置的值操作唯一,直接倒推到不能继续即可。
复杂度
H. Scenery
不会
J. Son of Pipe Stream
Problem
有一个 个点 条边的网络,每条边有一个容量 。
你需要运输两种液体 , 的源点为 , 的源点为 ,两种液体的汇点都为 。
在管道中可以同向运输两种液体,但不能同时双向运输。两种液体的体积比为 ,你能在一条管道内运输质量为 的 液体和质量为 的 液体当且仅当 。
假设你最后运输了质量为 的 液体和质量为 的 液体,你的分数为 。
求出一种方案使得你的分数最大化。
Sol
显然可以给答案乘上 后变为 的问题。
考虑 的限制。设只考虑 液体的最大流为 ,只考虑 液体的最大流为 ,考虑两种液体的最大流为 ,则一定满足如下限制:
此时两种液体可以交换,因此可以不考虑双向流动的情况。
考虑先处理完 液体的流,再考虑此时 液体的最大流。考虑此时的割集:
如果割集包含 ,则在 液体没有流时割边流量和大于等于 ,此时的流量和一定大于等于 。
如果割集包含 不包含 ,则在 液体没有流时割边流量和大于等于 ,因为 液体流入这部分的流量等于流出的流量,因此此时割集流量和大于等于 。
因此最小割一定大于 ,这说明上面的结论成立。
此时最优解一定满足 ,可以三分求出最优解的位置。
最后考虑求方案。先将两种液体整体流一次,求出每条边的方向和流量。然后每条边只保留这么多流量,分别对两种液体求一次网络流即可。
复杂度
K. Tarot Sham Boast
Problem
有一个长度为 的字符串, 每一位均为随机生成。
给出 个串 ,它们的长度相同。
将它们按照它们在随机串中出现的概率排序。
,字符集大小为 。
Sol
根据歌唱王国的结论,一个串出现的期望时间为 。
因此可以直接感性理解,计算上面这个值并排序即可。计算这个值可以使用KMP。
唯一需要注意的是,上面的期望计算方式中,一个长度为 的border参与计算当且仅当两个串重叠在一起,重叠长度为 。因此长度小于 的border需要被忽略。
复杂度
L. Visual Python++
Problem
给出二维矩阵上 个左上角和 个右下角,左上角 和右下角 构成了一个矩形,称矩形的边界为矩形内满足 x=x_1\or x=x_2\or y=y_1\or y=y_2 的点。
你需要将角之间两两配对形成 个矩形,要求这 个矩形之间两两要么不交要么包含,且边界不能相交。输出任意一个方案或输出无解。
Sol
考虑 最大的一个左下角(如有多个考虑 最大的),设这个角为
考虑此时它能匹配的所有右下角,找到其中 最小的一个 。
如果 不匹配 ,假设 匹配了 满足 ,此时假设 匹配的左上角为 ,则此时 ,,此时这两个矩形一定相交但不包含或者边界相交。
因此 只能匹配它能匹配的中 最小的。考虑从下往上扫依次考虑每个点的匹配。扫到一个右下角就加入集合,对于一个左上角,此时相当于在集合中 大于等于它的中选一个 最小的。set维护即可。
最后考虑判断合法,相当于有若干条线段判断是否相交,可以再做一次扫描线。
复杂度
2018 ACM-ICPC World Finals
C. Conquer the World
Problem
有一棵 个点的树,边有边权。
点 上初始有 个人,你希望通过移动人的位置,让点 上至少有 个人。
最小化每个人移动的距离和,输出最小值。
Sol
称人为流量,点 上至少有 个人为需求。
考虑一条链上的问题,显然这是一个费用流模型。
考虑在链上从从左往右扫,依次加入所有的流量。
如果不存在反悔操作,则直接使用set记录当前左侧没有使用的流量,每次加入一个需求时按照距离从小到大匹配即可。
但可能存在反悔操作,即费用流增广时流反向边的情况。
考虑一个匹配 :
如果 反悔去匹配后面的一个 ,则相当于撤销这次匹配,因此代价为 ,这可以看成一个位置为 的流量,匹配这个流量相当于撤销之前的匹配。(在链上点不带权的模型中,一定不会用这个匹配)
如果 反悔去匹配后面的一个 ,则代价为 ,可以看成一个位置为 的需求。
对于 的情况同理。
一个代表撤销操作的点可以继续匹配,因此多次匹配后一个点可以代表若干次撤销,而匹配这个点代表撤销上一次匹配时的所有操作,可以发现这样的点参与上面的匹配时,反悔的代价仍然是这个。
考虑加入一个点,设它增广路的结尾为点 ,则 的匹配一定反悔,这会导致导致包含 的匹配点反悔。考虑看成匹配了这个匹配点,可以发现这样匹配的最短路一定等于增广路上的最短路(不然之前的匹配不是最优),因此每次加入点只需要和之前的一个点匹配。
考虑顺序扫过去,遇到一个流量时,如果它和一个需求匹配能减小费用则匹配,否则不动。遇到一个需求时,先看成它和位置 匹配,然后再做反悔。这也可以看成先将匹配点加入,然后取能让代价减小的匹配,一直取到不存在这样的匹配。
如果一个匹配的两侧都反悔去匹配后面的点,则此时两个匹配一定交叉,此时一定不优。因此每次加入的两个点最多有一个改变,因此操作次数为 ,使用堆即可做到
考虑树上的情况,此时两点匹配代价变为 。
从下向上维护匹配,记录点的深度,在点 处处理所有 在这个点的匹配,此时可以看成将它所有儿子的两种点分别合并,然后取能让代价减小的匹配。反悔时类似的处理代价即可。使用可并堆即可做到1log
可以将深度相同的点合并,这样的复杂度为 。
D. Gem Island
Problem
有 个人,初始每个人有一个
每一天随机选择一个人,以 的概率选中 ,然后将这个人的 加一。
求出 天后, 最大的 个人的 和,输出实数。
Sol
输出实数导致容斥过不去
可以将这个概率乘上 变为方案数,考虑一种最后 出现的方案数。
考虑每一次加一给了谁,则这部分的方案数为
再考虑每一个人每次加一的系数,这部分为 ,总的方案数即为上两个相乘。
因此可以发现每种可能的 出现概率相等。
设 表示此时的答案, 表示 个非负整数和为 的方案数。考虑枚举有多少个人最后 ,然后再让剩下的人每个人 减一,则有:
最后除以 即可,显然 。
复杂度
E. Getting a Jump on Crime
Problem
有一个 的网格,其中每个格子均为 的正方形。每个格子有一个高度 。
你初始在某一个格子的中心,你可以通过跳跃到达其他格子的中心。
你跳跃的初速度 给定,你可以选择跳跃的水平方向速度 和竖直方向速度 ,满足 ,忽略空气阻力, 秒后你的速度向量可以看成 ,其中 为重力加速度, 给定。你必须正好降落在格子中心。在跳跃的过程中,你不能碰到其它格子,即在这些格子上时高度不能小于等于这个格子的高度。
对于每个格子,求出跳到这个格子需要的最少跳跃次数或输出不能到达。
Sol
考虑一次跳跃,可以看成你从原点出发,必须经过 ,则需要满足:
这是一个关于 的二次方程,可以得到两个可能的 。
可以发现对于两个这样的抛物线, 更小 更大的那个一定在更上方,因此可以选择合法的里面 最小的。这样跳跃的曲线唯一。
然后考虑判断会不会碰到其它格子,因为曲线是上凸的,可以找出路线上每次经过横向或者纵向的边界的时刻,判断这些时刻即可。这样的时刻只有 个。
此时可以判断能否从一个点跳到另外一个点。然后bfs即可。
复杂度
G. Panda Preserve
Problem
给一个 个点的简单多边形,你需要在多边形内找一个点,让这个点到多边形所有顶点的距离的最小值最大。输出最大距离。
Sol
对于每个顶点,考虑求出平面上满足与它的距离小于等于与其他顶点的距离的区域。即 个顶点的 Voronoi diagram。
因为数据范围不大,考虑 Voronoi diagram 的暴力做法,对于每个点 ,考虑另外一个点 和它的垂直平分线,可以发现与 的距离小于等于与 的距离的点即为垂直平分线一侧的点,因此对所有平分线求半平面交即可。复杂度 。
考虑答案可能在的点,显然在多边形上距离一个点最远的点一定是一个顶点,因此对于点 ,答案只可能在如下两种点:
- Voronoi diagram 上距离 最近的点组成的多边形的顶点(如果在简单多边形内)。
- Voronoi diagram 上距离 最近的点组成的多边形与给出多边形的交点。
可以发现 Voronoi diagram 的总点数边数为 级别,因此对于第一部分,可以对于每个点暴力判断它是否在多边形内。对于第二部分,可以枚举 Voronoi diagram 的线段和多边形的线段求交点。
复杂度
H. Single Cut of Failure
Problem
给一个矩形的边框,有 条线段,每条线段的端点都是边框上的点且不在角上,且两个端点不在同一条边框上。
你需要画若干条线段,每条线段端点都是边框上的点,使得给出的每一条线段至少与你画的一条线段相交。
找一种画的线段数量最小的方案,输出方案。
Sol
因为不存在在同一个边框上的点,因此连接两条对角线一定满足要求,因此只需要判断是否能一条线段解决问题。
枚举第一个端点所在的位置,此时另外一个端点的位置限制之和第一个端点右侧区间中右端点的最小值以及左侧区间中左端点的最大值有关。二倍环长变成链后前后缀和即可。
复杂度
如果没有性质,注意到选 条线段可以看成选 个分界点,可以使用类似 Surveillance 的倍增做法同样做到 。
I. Triangles
Problem
给一个 的三角形点阵,其中相邻的边中有一些存在,有一些不存在。
求这个图中的三角形数量。
Sol
考虑先求出 形状的三角形数量,另外一个方向同理。
枚举底边所在的行,记 表示位置 向右侧延伸的长度, 表示位置 向右上延伸的长度, 表示位置 向左上延伸的长度。
则 合法当且仅当:
rb_{i,j}\geq k-j\and sr_{i,j}\geq k-j\and sl_{i,k}\geq k-j
对于一个 ,可以求出只考虑限制 时合法的 的后缀。对于 也可以求出只考虑限制 时合法 的前缀。
此时相当于有序列 ,求有多少对 满足 ,可以发现这类似于二维数点,扫过去树状数组维护即可。
复杂度
J. Uncrossed Knight's Tour
不会
2019 ICPC World Finals
B. Beautiful Bridges
Problem
Sol
考虑 表示上一个柱子在位置 ,前面的最小代价。只需要快速判断一个连边是否合法即可 dp。
显然判断合法只需要判断中间的关键点是否都在圆弧的下方。设当前位置为 ,上一个位置为 ,则对于一个关键点 ,需要满足:
y-h+\frac{x_2-x_1}2\leq\sqrt{(\frac{x_2-x_1}2)^2-(x-\frac{x_2+x_1}2)^2}\\ y-h+\frac{x_2-x_1}2\leq 0\or (y-h+\frac{x_2-x_1}2)^2\leq (\frac{x_2-x_1}2)^2-(x-\frac{x_2+x_1}2)^2
此时如果只把 看成变量,则第一个限制相当于 一个值,第二个限制相当于
因此一个关键点的限制形如 ,因此考虑 从大到小扫,依次加入限制并合并即可。
复杂度
C. Checks Post Facto
不会
F. Directing Rainfall
Problem
二维平面上有 条线段,满足如下条件:
- 没有两条线段相交。
- 不存在线段平行于坐标轴。
一个点从 开始下落的方式如下:
初始这个点在 ,随后这个点开始竖直向下移动。如果这个点碰到了一条线段,则它会沿着线段移动到端点再开始自由下落。下落到 时停止。
你可以在线段上放洞。如果你在一条线段上放了一个洞,则点沿着线段运动的过程中碰到洞时会离开线段开始向下下落。
你需要放尽量少的洞,满足如下条件:
给定 ,存在 ,使得一个点从 开始下落,停止时横坐标在 之间。
输出最小的洞数量。
Sol
设 表示从横坐标 出发时,至少需要放多少个洞。
在没有线段的时候,显然
考虑加入一条线段,满足这条线段在之前所有线段的上方。设这条线段端点为 ,考虑 的变化:
如果 ,则此时:
如果转移中只考虑第一部分,则相当于区间加一,然后区间做前缀max。考虑线段树维护 的差分。则前缀max可以看成对于差分后一个小于 的位置,在它后面找一些差分大于 的位置(或者到结尾),然后将这部分同时抵消。因此可以从后往前,每次找到最后一个差分为负的位置,然后从这个位置向后抵消,使用set/map维护即可。因为每次至少抵消一个位置,而插入次数为 ,因此均摊复杂度
对于第二种转移,可以看成整体取min。注意到做完上面操作后 单调,因此这里一定是改变一段前缀。直接做即可。
因此只需要将所有线段排序,满足一条线段在它前面线段的上方,即可 维护 。
这样的顺序显然存在。考虑按照 扫描线,维护当前线段的顺序,因为不存在相交所以顺序不会改变,可以用set维护。在加入一条线段时,先找到它加入的位置,然后考虑从它上面的那个线段向它连有向边,它向它下面的线段连有向边,这里一条有向边 表示 在 下方,因此在最后的顺序中 应该在更后面。
可以发现只要每次加入时都满足顺序,则这样的顺序即为合法的。因此对上面得到的图拓扑排序即可得到合法的顺序。
复杂度
G. First of Her Name
Problem
有 个字符串,其中第 个字符串为在第 个字符串的开头加入字符 得到的。
次询问,每次给出一个字符串 ,询问 个字符串中有多少个字符串包含 作为前缀。
,给定字符串两两不同。
Sol
可以直接做树上后缀排序
考虑翻转所有串,则变为在后缀加入字符,询问多少个串包含后缀。此时给定串构成Trie的关系。
相当于给一个Trie,多次询问有多少个串包含一个后缀。这显然是 广义SAM AC自动机的经典应用。
建出AC自动机(广义SAM)后,每次询问先直接定位询问串,然后相当于数有多少个串能通过fail连接到达这个串。预处理即可。
复杂度
I. Karel the Robot
Problem
Sol
如果只有一个程序,则它可以看成一个顺序执行,包含条件跳转的结构。在if
的开头和 until
的开头结尾分别有条件跳转。顺序执行这个程序即可。
因为机器人的运动只和位置有关,可以设 表示当前机器人在 ,面向 ,当前执行到了第 个位置,程序结束时机器人的位置。考虑记忆化搜索转移,可以发现如果转移发现了环,则环上的所有点开始都无法结束。可以同时记录每个 是否会结束,然后直接记忆化搜索即可。
考虑多个程序的情况,设 表示当前执行到了程序 的第 个位置,其它定义与上面相同,程序 结束时机器人的位置。则遇到一个形如 B
的调用函数的语句时,这个语句结束时的状态一定为 。因此可以同样使用记忆化搜索,转移出现环则环上的状态都无法结束,记录每个状态的访问状态(是否访问过/是否在栈中)即可。
复杂度
可能空间是256mb,可能需要稍微注意一下空间
J. Miniature Golf
Problem
有 个人,每个人有 个正整数
任意选择一个正整数 ,此时第 个人的得分为 ,第 个人的排名为分数小于等于他的人的数量。
对于每个人,求出 任意时他可能的最小排名。
Sol
显然一个人的得分对于 为一个 段的分段线性函数,因此对于两个人,可以在 的时间内,求出使得第一个人分数大于等于第二个人分数的 区间。这样的区间一定只有 段。注意细节
考虑对于一个人 求出他的最小排名。依次考虑其他人,分别求出使得 的分数大于等于这个人分数的 区间。此时将这些区间合并,相当于找到一个位置使得这个位置被所有区间覆盖的次数最少。直接对区间排序扫过去即可。
复杂度
K. Traffic Blights
Problem
在直线上有 个交通信号灯。第 个灯在原点向右 米,它显示红绿的规则为先显示 秒红灯,再显示 秒绿灯,然后循环。
在时刻 ,所有交通信号灯正好变为红灯。一辆车在 中的随机一个时刻开始从原点出发,速度恒定为 ,遇到第一个红灯时停止。
对于每个交通信号灯求出车停在这里的概率,并求出车不停止直接通过的概率。
, 两两不同,所有数都是非负整数。
Sol
灯循环的周期为 ,显然 被这个值整除,且所有灯的变化都出现在整数时刻,因此可以变为枚举周期中每个长度为 的时间段 ,计算这个时间段内出发停止的位置。 停止一个位置的总次数除以 即为答案。
但直接枚举显然不行,根据CRT,枚举 可以改为枚举 。对于这里面的大质数(比如 ),可以发现 的值只影响所有循环节长度为 的灯,且这些灯只被这个值影响,因此这些灯与其他灯独立。因此可以求出只考虑循环节为 的灯,停在每个灯的概率。然后可以合并。
对于其他的循环节,它们之间不一定独立。考虑将这种情况转换为上一种情况,令 ,这个值满足 。枚举 ,设 ,考虑对于一种 其所有的 算答案。
此时可以枚举 ,可以发现对于任意 , 一定是一个质数 ,因此考虑 增加时,它的循环节一定是一个质数。
此时考虑 的变化,每个灯的循环节都是一个质数,每种循环节间独立。对于同一个循环节 ,可以求出考虑所有循环节为 的灯,车停在每个路灯的概率。这可以通过预处理每个灯每个 时,一个循环节 内的通行情况,然后bitset优化 对应所有灯,求出只考虑自己这一类的灯时的答案。
最后车停在某个位置当且仅当这一类中车停在这里,且其它类中车停在后面,可以从后向前扫过去求出。
复杂度
可以发现,循环节为 的所有路灯也是可以放在一起考虑的,设最大的循环节为 ,枚举 后显然前面的循环节也都可以计算。
因此可以选择更小的 ,只需要满足对于任意 , 一定形如 即可。此时可以发现取 就能满足要求。复杂度降至
-
-
- 2020 集训队作业 题解
- 2013-2014 ACM-ICPC, NEERC, Northern Subregional Contest
- 2014-2015 ACM-ICPC, NEERC, Northern Subregional Contest
- 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest
- 2016-2017 ACM-ICPC, NEERC, Northern Subregional Contest
- 2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest
- 2013-2014 ACM ICPC Central European Regional Contest
- 2014-2015 ACM-ICPC, Central Europe Regional Contest
- 2015-2016 ACM-ICPC, Central Europe Regional Contest
- 2016-2017 ACM-ICPC, Central Europe Regional Contest
- 2017-2018 ACM-ICPC, Central Europe Regional Contest
- 2013-2014 ACM-ICPC Northeastern European Regional Contest
- 2014-2015 ACM-ICPC Northeastern European Regional Contest
- 2015-2016 ACM-ICPC Northeastern European Regional Contest
- 2016-2017 ACM-ICPC Northeastern European Regional Contest
- 2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest
- 2014 ACM-ICPC World Finals
- 2015 ACM-ICPC World Finals
- 2016 ACM-ICPC World Finals
- 2017 ACM-ICPC World Finals
- 2018 ACM-ICPC World Finals
- 2019 ICPC World Finals
- 2020 集训队作业 题解
-