XXII Open Cup. Grand Prix of Seoul 部分题解
作者:互联网
比赛链接:https://codeforc.es/gym/103855。
A. Factory Balls
题意
给出 \(n\) 个编号为 \([1,n]\) 的点,初始每个点的颜色都为 \(1\)。有 \(m\) 种装备,每种装备会遮住一些位置(不一定是连续区间)。每一个时刻可以进行如下操作之一:
- 选择一种颜色 \(1\le i\le k\),将所有没有被装备遮住的位置染上颜色 \(i\)。
- 选择一个没有装上的装备装上它。
- 卸下一个装备。
给出每个位置最后的颜色 \(c_i\),问达到这种状态并且没有装任何装备最少需要多少步。无解输出
-1
。数据范围:\(1\le n,k\le 10,0\le m\le 10\)。
题解
看到范围很小,考虑暴力。
直接 DP 是不行的,那就直接 BFS。
队列里存下状态 \((s,t)\),其中 \(s\) 表示每个位置是否为最终要求的颜色,\(t\) 表示每个装备是否被装上。
可以直接暴力枚举这一时刻做哪种操作。时间复杂度 \(\mathcal{O}(2^{n+m}(nk+m))\)。
代码
https://paste.ubuntu.com/p/trGBgXzjNC/
C. UCP-Clustering
题意
略。
其实是懒得写
题解
大胆猜一手,直接暴力复杂度是对的。
然后真过了???
看题解后发现状态数其实是 \(\mathcal{O}(n^2)\) 的,具体我也不想写了。
注意求中位数的时候可以用 nth_element
和 max_element
相结合,这样可以去掉排序的 \(\log\)。
那么总复杂度就是 \(\mathcal{O}(n^3)\) 的。
代码
https://paste.ubuntu.com/p/pB5jYDWcbh/
D. Triple Sword Strike
题意
二维平面上有 \(n\) 只怪兽,每个怪兽有一个整数坐标 \((x,y)\) 和价值 \(v\)。你可以砍三刀,每次只能沿着平行于坐标轴的方向砍,每砍一刀就会杀死这一条直线上的所有怪兽。问杀死的怪兽的价值总和最大是多少。
数据范围:\(1\le n\le 3\times 10^5,0\le x,y\le 10^6,1\le v\le 7000\)。
题解
对于每一个横坐标和纵坐标开一个桶记录这条直线上的怪兽价值和。
那么拿一个 multiset 就可以直接求出砍得三刀都是横坐标/纵坐标的情况。
另外两种情况可以枚举哪一个横坐标/纵坐标只砍一刀,减去会算重的怪兽的价值,可以用 multiset 删除插入完成,最后再算一遍就行。
代码
https://paste.ubuntu.com/p/Pd8NyWS7nb/
E. RPS Bubble Sort
题意
给一个长度为 \(n\) 的由 \(\{\texttt{R,P,S}\}\) 组成的序列 \(a\),问进行 \(t\) 轮“RPS 冒泡排序”后序列的形态。
其中,一轮“RPS 冒泡排序”的流程是:
- 从 \(i=1\sim n-1\) 顺序扫过去,如果 \(a_i\) 能赢 \(a_{i+1}\),那么就交换 \(a_i\) 和 \(a_{i+1}\)。
数据范围:\(2\le n\le 5\times 10^5,1\le t\le 10^9\)。
题解
妙妙题~
考虑如果只有两种字符怎么做。那么一轮操作肯定是把赢的那一个字符放到后面。
具体的,假设第 \(i\) 个输的字符在位置 \(x\),那么 \(t\) 轮操作后它就在位置 \(\max(x-t,i)\)。
如果有三种字符呢?
结论:从前往后扫,每一个极大的只包含两种字符的连续段是独立的,即它们不会相互影响。
证明:考虑一次操作之后,当前连续段会把赢的那一个字符放到最后面,而下一连续段的开头肯定不同于当前连续段的两种字符。如果下一连续段的另一种字符(即不同于开头的字符)会因为输给了开头的字符而向前,又因为输给了当前连续段的一个字符而影响到当前连续段,它就输给了两种字符,不符合 RPS 的游戏设置。
因此,我们只需要把所有连续段拿出来做只有两种字符的情况就可以解决这个问题了。
时间复杂度 \(\mathcal{O}(n)\)。
代码
https://paste.ubuntu.com/p/wZWhfDNvNJ/
F. Stones 1
题意
\(n\) 个黑白石子排成一行,每个石子有一个权值 \(a_i\)。
每次你可以移除一个石子 \(i\),如果当前要移除的石子的颜色和 两边相邻的还未被移除的石子 的颜色都不同,那么你的分数就加上 \(a_i\)。
问最大分数。
数据范围:\(1\le n\le 3\times 10^5\)。
题解
首先,不难发现连在一起的相同颜色的石子只有权值最大的那一个有用,那么就可以把这个连续段缩成一个点。
结论:设缩完后有 \(m\) 个点,那么答案就是第 \([2,m-1]\) 个点里权值最大的 \(\lceil\frac{m-2}{2}\rceil\) 个之和。
证明:容易发现两边的肯定没用。对于剩下的,一定会有一种方式取到最大的 \(\lceil\frac{m-2}{2}\rceil\) 个数,题解使用了归纳法证明,这里不再赘述。(可以考虑手玩(雾
知道结论后就很好做了。
代码
https://paste.ubuntu.com/p/PfzmQPxmpK/
H. Beacon Towers
题意
给出一个 \(1\sim n\) 的排列,你需要把排列划分成若干段,使得每一段的最大值递增。问方案数对 \(998244353\) 取模的结果。
数据范围:\(1\le n\le 5\times 10^5\)。
题解
结论:只有是前缀最大值的数才有用。即每一个段里都至少有一个前缀最大值。
证明:如果一个段里没有,那么它的最大值一定都比两边小。
把这些数的下标拿出来,答案就是 \(\prod(p_i-p_{i-1}+1)\)。
代码
https://paste.ubuntu.com/p/5bdKFjDVKZ/
J. Exam
题意
给出一个 \(n\times n\) 的矩阵,每个位置上有一个数 \(a_{i,j}\)。问有多少条从 \((1,1)\) 到 \((n,n)\) 的路径满足:
- 依次写下路径经过的位置上的数,写下的序列最大子段和恰好为 \(k\)。
数据范围:\(1\le n\le 20,-4\times 10^{10}\le k\le 4\times10^{10},-10^9\le a_{i,j}\le 10^9\)。
题解
数据范围很小,又不能直接爆搜,考虑 Meet-In-the-Middle。
恰好为 \(k\) 的路径数量 \(=\) \(\le k\) 的路径数量 \(-\) \(\le k-1\) 的路径数量。
对于每条经过的路径,记录当前已知最大子段和,以及最大前缀/后缀和。
先过滤掉最大子段和 \(>k\) 的路径,在合并的时候用排序+双指针求符合条件的路径数量。
实现时要注意一些边界情况。
这种题见过几次了,一定要想到 MIM 的技巧!
代码
https://paste.ubuntu.com/p/N8McdgjwGv/
K. Board Game
题意
略。
同样懒得写
题解
结论:如果一个棋盘的行数和列数都 \(\ge 2\),那么删掉这个棋盘的最后一行和最后一列不影响赢家。
证明:考虑如果先手已经到了最后一列,那么下一步后手再往下走肯定不劣;同理如果后手到了最后一行,先手下一步往右走也不劣。所以直接去掉对答案没有影响。
(这个证明比较感性,详细可以看官方题解。)
但删掉之后并不能直接满足,要保证能够从 \((1,1)\) 到达 \((n,m)\),所以还要调整。
那么我们已经缩成了若干 \(1\times m\) 或 \(n\times 1\) 的矩形,直接判断先手和后手谁能走更多步就行了。
代码
https://paste.ubuntu.com/p/sKNxkzYMDy/
M. Short Question
题意
给定两个长度为 \(n\) 的数列 \(p,q\),求 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^n\min(|p_i-p_j|,|q_i-q_j|)\)。
数据范围:\(1\le n\le 10^6,1\le p_i,q_i\le 10^6\)。
题解
首先你要发现,\(\min(x,y)=x+y-\max(x+y)\)。
把式子化开后会发现,如果我们把 \((p_i,q_i)\) 看成若干平面上的点,那么实际上我们就是要求它们两两之间曼哈顿距离之和减去切比雪夫距离之和。
把切比雪夫距离转成曼哈顿距离,由于行列独立,可以分开排序后直接计算。
代码
https://paste.ubuntu.com/p/qJjRfmWRjY/
标签:10,le,Seoul,XXII,字符,题解,https,题意 来源: https://www.cnblogs.com/xsl19/p/cf-gym103855-sol.html