Codeforces 题解集合
大概只会放 *2000 以上的题目上去了
[Change Log]
created on 2022.5.6
latest updated on 2022.12.6
- Div1
- Div1 + Div2 & Global Round
- Div2
- Education Round
- Round 42 (Rated for Div. 2)
- Round 47 (Rated for Div. 2)
- Round 84 (Rated for Div. 2)
- Round 115 (Rated for Div. 2)
- Round 116 (Rated for Div. 2)
- Round 117 (Rated for Div. 2)
- Round 118 (Rated for Div. 2)
- Round 119 (Rated for Div. 2)
- Round 120 (Rated for Div. 2)
- Round 125 (Rated for Div. 2)
- Round 127 (Rated for Div. 2)
- Div3/4
- 野场
Div1
先留着(
Div1 + Div2 & Global Round
Global Round 20
D. Cyclic Rotation ( )
构造,双指针, multiset,逆向,等价变换
题意
给定长度为 的数组 ,和 的一个排列数组 ,对 进行操作:
- 如果 ,则 。
询问能否对 进行任意次操作得到
数据范围
思路
- 对操作进行等价变换,每次对 的操作相当于把 删除, 在 前拷贝一份 。
- 尝试逆向,我们看能否从 得到 。
- 双指针构造方案:
- 指向 最后一个元素,维护一个
multiset
while (b[j] == b[j - 1]) j--;
,向 multiset 中插入- 如果 ,
i--,j--
- 否则,在 multiset 中查找 ,找到则
i--
否则无解。
- 指向 最后一个元素,维护一个
- 因为每次操作, 的位置其实相对是不变的,然后根据第一点,我们从右往前查 multiset中没有的元素一定不合法。
Solution
Global Round 21
D. Permutation Graph ( )
构造,分治,或数据结构贪心
题意
给定长度为 的排列,有 个点,两点 l, r 之间当且仅当下标区间在 中 为区间的两个最值,可以连边,询问从 的最短路。
数据范围
思路
- 抓住题目性质,先找到区间最大值的位置 ,假设
- 横跨 的区间两点是不可能连边的,所以分治求解
- 对于 ,我们找出 [1,pos] 区间的最小值位置 ,递归求解 , 且 返回 1。
- 对于 求解方式相同,依次递归出口为两端点相同。区间满足条件
l != 1 && r != n
就表明是区间两最值端点应当 return - 然后需要一点细节,就通过本题,时间复杂度为 。
Solution
Div2
Round #264 div2
D. Bear and Floodlight ()
状压DP,简单计算几何
题意
在二维坐标上,一个人从 走到 ,有 盏路灯,每盏灯的照射角度最大为 ,坐标为 。询问这个人最多能走多远,到 停止。
数据范围
思路
- 观察数据范围, ,两种想法,选和不选和二进制枚举,自然是二进制枚举。
- 涉及二进制枚举,一个很自然的想法是状压DP,设计一下状态。
- 发现对于每盏灯的贡献和当前所在点有关。不妨设状态 表示状态为 时能到达的最远距离。
- 状态转移:
f[i | (1<<j)] = max(f[i|(1<<j)], calc(f[i], j))
,calc 表示当前在 f[i] 点,第 盏灯能到达的最远距离 - 计算
calc()
函数- 可以用
atan2
求出 对应的角,用内角和算出 对应的角,然后用其补角 tan 求出 ,进而求出 - 也可以用旋转矩阵,先求出向量 做逆时针旋转矩阵新的向量 ,那么
- 两种情况都需要特判,最远点是无穷大或者其他边界问题。
- 可以用
- 目标答案为 ,时间复杂度为
Solution
E. Bear in the Field ()
矩阵快速幂
题意
在大小为 的棋盘上,一个点起始坐标为 起始速度是 ,询问经过 秒后的位置,对于每一秒:
- 点处于 ,给速度的贡献为 , 速度将变为
- 移动到 , 这里的 已经更新
- 每个点给速度的贡献 。
数据范围
思路
- 观察数据范围, 很大很大,相当于询问你经过 步之后的位置,显然的矩阵快速幂。
- 状态矩阵参数: 其中 其实代表当前经过的时间。
- 转移矩阵,先看如何转移:
- 因为运算过程中涉及对 取模,先将坐标下标从 开始比较好算。
- 故状态矩阵为
- 时间复杂度为
Solution
Round #564 div2
D.Nauuo and Circle ( ) (结论、计数)
题意
给了一颗 个节点的树,询问存在多少种合法排列,使得 个点在圆环上排列对应位置上,相连的边不会有相交。
答案模
数据范围
思路
- 核心点:一个结论:一个节点的子树所有点在圆环上连续的一段。
- 所以一个节点的子节点可以有阶乘级别的排列。
- 更正式的表达,
- 由于整棵树根可以随意设置,但最后效果其实和 放在 个位置上的效果一样, 所以最后答案等于 , 而实际上把每个点的度数阶乘相乘即可。
Solution
Round #747 div2
C. Make Them Equal ( )
题意
输入长度为 的字符串 和一个字符 ,可以进行一个操作,对于 ,可以将不能整除 的 ,所在的下标字符替换成 ,问最少经过多少次操作可以使 每个字符都是 ?
思路
- 由整除出发,
- 对于 而言, 都可以被替换。
- 对于 而言, 可以被替换。
- 因此最多需要2次操作就可以将 替换成想要的字符串。
- 对于做 次操作,遍历数组就行。
- 对于做 次操作,当数组中, 及 的倍数下标位置的字符都是 的话,只需要一次操作就可以把 都替换成 ,输出 的下标。
- 对于做 次操作,就是 , 及 的倍数下标位置的字符都是 ,输出 和 。
赛中
上述的第一点想到了,但是忽略了做1次操作的做法,也是这道题的核心,由第1点衍生出,可以替换不是它倍数的下标位置(其实就是题意)。太蠢了
Solution
Round #782 div2
D. Reverse Sort Sum ( )
构造、逆序操作
题意
求一个长度为 的 01 数组 ,对 进行 次操作, 每次对 的区间进行排序结果累加到 数组中,已知 数组求 数组。
数据范围
思路
- 观察1:将 数组求和 可以得到 的个数 。由贡献思考
- 观察2:如果 ,那么 。
- 由观察1得到 1 的个数,抓住题目性质,在第 次操作时,是由后缀为 个 的数组累加。 已经求出,看前 位,如果我们把第 次的后缀累加给撤销,得到的 其实是第 次操作累加之后的 的前 位,这时候可以不用管 。然后同理如果 。就这样往前递推。
- 但需要注意,如果该位为 , 需要减 1,很好理解,在 之前 没有在排序范围内自然也不属于后缀。
- 涉及区间更新操作就懒得 搞来搞去了,直接上差分树状数组,复杂度 。
Solution
Round #788 div2
E. Hemose on the Tree ( )
构造
题意
给了 个点的树, 是 的幂次,边权和点权是 的排列。询问从任意点为根,从根出发途中经过的的点和路径权值 最大值的最小值是多少?
数据范围
思路
- 首先如果单独选一个大于 的点为根,最大值 ,所以考虑根权值为 ,并且途径最大值为 ,其实就是一个构造
- 接下来需要 对数分别为
- 分类讨论构造一下
- 父节点 ,子节点值为 ,边为
- 父节点 ,子节点值为 ,边为
- 这样构造到根的子节点,异或和为0,而由于根大(指大于 ) ,那么子节点小,到了子节点到子节点的边异或值为 ,到了子节点的子节点异或值为 ,如此循环往复,所有值一定
Round #789 div2
D. Tokitsukaze and Meeting ( )
DP + 行列分开计算贡献
题意
往 矩阵左上角里塞 0 和 1, 列的元素前往下一行第1列, 依次后移, 询问每一次行和列中有多少个行和列里有
数据范围
思路
- 行列分开考虑.
- 对于列, 进入 0 答案不变, 进入 1 如果第一列此时没有元素为1, 列答案++
- 对于行, 答案显然与 i - m 的行答案有关系, 相当于新加入了一行, 如果这行中有 1, 则行答案++, 具体实现见代码
Round #795 div2
D. Max GEQ Sum ()
题意转换, 单调栈, 前缀和, 最值查询
题意
给了一个长度为 的数组 , 询问该数组是否满足任意连续子序列 满足:
数据范围
思路
- 题意转换: 实际询问从 向两边扩展, 在未达到更新最大值的位置 , 考虑一般情况下, 前缀和 是否成立
- 以上转换, 可以把问题拆分多个问题空间的不重不漏的子集.
- 显然需要用单调栈\笛卡尔树 求出左右两边大于 的第一个下标分别记为
- 则第一点的式子转化为是否存在 满足 .
- 即 , 仔细观察发现等式只需要只要其中一个和大于 就能满足了
- 故问题转化为求是否
- 实际代码形式:
querysuf(L+1, i-1) - suf[i] > 0 || querypre(i + 1, R - 1) - pre[i] > 0
, 时间复杂度为
Solution
Round #801 div2
C. Zero Path ( )
方格dp、思维
题意
询问在大小为 的方格中,每个格子上值为 或 ,是否存在一条从 到 的路径,满足路径和为
数据范围
思路
- 这个题很重视观察性质。
- 如果 为偶数,则最后一定经过 奇数 个格子,此时无解。 那么一定经过偶数个格子。
- 明显可以通过 dp 预处理出到达每个格子的最大值和最小值。如果 的 包含 则有解,否则无解,证明:
- 如果不包含显然无解。证明包含一定有解。
- 因为经过偶数个格子,最后的和一定是偶数,(奇数-奇数,偶数-偶数)
- 如果进行一次调整让和变化,一定是 。因为本来和就是偶数,所以只要区间包含 0, 一定可以调整到和为 0, 证毕。
- 时间复杂度 ,代码上还需要一些细节。一道不错的题。
Solution
Round #802 div2
C. Helping the Nature ( )
差分、构造
题意
给了长度为 数组 ,可以进行三种操作:
- 对任意前缀所有元素 .
- 对任意后缀所有元素 .
- 对全部元素 .
询问最少经过多少次操作可以将所有元素置
数据范围
思路
- 由于是区间操作,不妨用差分来思考
- 构造差分数组
b[i] = a[i] - a[i - 1]
, 目标状态 全为 - 对于三种操作,等价于对差分数组:
b[1]--, b[i>1]++
b[n + 1]++, b[i<=n]--
b[1]++
- 所以先将 的所有 b[i] 全部设为 ,最后将 置 ,将 置 三种操作都可以,贪心取最划算的即可。
- 时间复杂度
Solution
Education Round
Round 42 (Rated for Div. 2)
E. Byteland, Berland and Disputed Cities ( )
贪心
题意
给了 个点,坐标 。每个点属于 P,B,R
其中一个。
询问在 {P,B}
点集中连接所有点和 {P,R}
点集中连接所有点,两者加起来的花费最小值。
思路
- 一点点考虑发现是个贪心分类讨论题。
- 对于没有 P 点存在,答案很显然。
- 如果两个 P 点中夹杂 B/P。对于这一段连接方式有两种。
- 相邻两点不管什么颜色直接连接。
- 先连接这一段的两个端点 P,这样在上一种连接方式下,可以扣除中间跨度最大的相邻点的连线,这样可能会更优。
- 时间复杂度 。
Solution
Round 47 (Rated for Div. 2)
这场vp, 打的很烂, D 题读漏条件, B 题贪错方向
B. Minimum Ternary String ( )
贪心
题意
给定长度为 的串, 只有 组成, 相邻 和 可以互换, 相邻 和 可以互换, 询问任意互换次数后整个串的最小字典序
思路
- 主要把握住题目条件, 发现 1 可以与 0 和 2 换, 所以不会有 1 在 2 之后, 第一个 2 之前的 0 在最前面, 之后相对顺序不变
Solution
C. Annoying Present ( )
贪心---货仓选址模型利用, 注意开 long double
题意
输入 , 表示长度为 的数组, 次操作, 每次操作有 和 , 每次操作选择一个下标 , 对数组所有元素加上 , 询问最终操作后数组平均值最大值
数据范围
思路
- 平均值最大 -> 数组和最大, 负数影响最小, 正数影响最大.
- 对和的贡献固定, 考虑距离的贡献, 由货仓选址模型可知, 距离和最小的选点应在中点, 反之最大的点应在边缘点, 之后便可求解该题
- 观察数据范围, 要开
long double
Solution
D. Relatively Prime Graph ( )
构造, 边上两点编号互质, 图要求连通
题意
给定一个图, 询问是否能构造出 个点, 条边的连通图, 任意边两端点编号互质
数据范围
思路
- 观察数据范围, 最多只有 条边, 对于每一个数与其互质小于它的数字个数为 , 累加到 左右时, 已经大于了
- 故可以暴力用
gcd()
判断两点互质来连边 - 记得是连通图, 即
Solution
E. Intercity Travelling ( )
组合数, 递推, 期望
题意
你要从 ,有 个站点 ,每个站点都有 的几率有休息点。你连续坐 站时,每两站间的疲劳值为 ,
如果第 站有休息点,那么你可以在此处休息,然后接下来的站点的疲劳值又从 开始。求 。
数据范围
思路
- 我们要求的其实是疲劳值之和, 直接算肯定不好搞, 要按贡献来算, 有两种思路, 考虑每两点之间的答案贡献, 考虑每个 的贡献, 前者请参考官方题解
- 计算每个 的贡献其实是求每个 的出现次数
- 考虑 , 由于 点的特殊性, 一定有一个 , 无论后面怎么走, 有 次, 考虑后面的 个点相邻两点 x 和 y, 一定是 x 休息, 其他点无所谓(但不考虑终点的休息)有
- 同样考虑 , 对于 点特殊考虑, , 2 及以后的店怎么搞无所谓, 有 次, 同样和前面一样, x, y, z 三个点, 一定是 x 休息, y 不休息, 其他点无所谓, 有
- 所以对于任意 出现次数为
Solution
Round 84 (Rated for Div. 2)
D. Infinite Path ( )
置换环、数论
题意
定义排列乘法 , 。自然有排列的幂次 。
给定在长度为 的排列 。和每个点的颜色 。询问最小的幂次 能存在一个
使得 都是同一种颜色。
思路
- 读完题目很容易联想置换环这个东西,每个点 向 连边,会形成若干个环。
- 对于每个环的内部,经过环的长度幂次 一定能存在一个 。
- 还有更快的方式就是,经过环的因子次 变换以后,会分成 个长度为 的小环。如果存在一个小环所有点颜色相同则 合法。
- 给一个样例
p: 6 5 4 2 1 3 color: 1 1 1 3 4 5
答案为 。
- 给一个样例
- 解法就是找出所有的环,再暴力枚举环长度的所有因子,来检验是否合法,简单分析复杂度是够的。
Solution
Round 115 (Rated for Div. 2)
这场是vp的,4题138罚时,performance在
E. Staircase ( )
经典放格计数, DP 预处理, 修改只考虑单点对答案的贡献
题意
一张 的图,有两种楼梯形,L
和 7
形,即向下向右和向右向下这样无限重复,单点和横着的两个点和竖着的两个点也算,有 个询问,每次将每个点的权值异或 ,如果某个点的值为 ,那么这个点就不能用,再询问贡献。
数据范围
思路
- 先处理所有格子都 free 的所有方案数,用 dp 来做
dp[i][j][0]
表示该点作为左下角的方案数、dp[i][j][1]
表示该点作为右下角的方案数- 所有状态初始化为 1, 状态转移:
dp[i][j][0] += dp[i - 1][j][1], dp[i][j][1] += dp[i][j - 1][0]
- 以每个格子结尾对答案的贡献就是
dp[i][j][0] + dp[i][j][1] - 1
- 然后再考虑对于每个询问来处理,每次询问给出 (x,y) 点,这里有一个处理技巧:只考虑这个点对答案的贡献
- 从该点出发(先假定这个格子 free),往上和往下最多能走的合法格子数,相乘-1就是贡献,当然注意有两种走法
自己想法
不会对每个询问贡献单独算,不太会处理所有格子free的方案数
Solution
Round 116 (Rated for Div. 2)
D. Red-Blue Matrix ( )
题意
给了一个 的矩阵,每个元素有一个值,现在要把矩阵的行染成蓝色或红色(必须两个颜色都有),染完后将矩阵切成左右两个矩阵,切割行为
左边矩阵红色元素都比蓝色元素大,右边矩阵蓝色元素都比红色元素
数据范围
思路
- 首先无论分割点在哪里,第一列永远要被考虑,如果将行按第一列元素大小排序,那么永远只有前缀行染成蓝色
- 然后枚举切割点和染色行检验合法性,要预处理顶点出发的子矩阵最值做到O(1)查询
自己想法
不知道第一列元素的重要性,甚至看了题解半天没反应出来怎么预处理子矩阵最值
Solution
E. Arena ( )
题意
有 个人,每人有 点生命值 () ,每次每人会对其他所有人造成 点伤害。
生命值低于 的会死亡,给出 和 ,问有多少种不同初始生命值情况会出现场上无人存活(没有赢家)
输出答案总数
数据范围
思路
- 观察数据范围,唯一有理做法就是 DP,复杂度大概在 左右
- 首先可以大致确定一个小阶段是进行的轮数,但并不一定用轮数作为一个dp的一个纬度,可能是其他与轮数相关的东西
- 询问剩余 人,多少种不同初始生命值的方案数,这个集合可以由 剩余 人,遭受了 次攻击的集合组成 ()
- 状态表示:
dp[i][j]
当前轮剩下 个人,已经遭受 次攻击的情况 - 考虑如何转移,遍历下一轮剩余的人数为 ,则被更新的状态是
dp[k][min(j + i - 1, x)]
- 状态转移:
- 个人里面选 个人死亡,死亡的 个人里的生命值组成情况可以是 范围。
Solution
Round 117 (Rated for Div. 2)
E. Messages ( )
题意
现有 名学生,老师希望学生 阅读消息 。
老师可以发布 条消息,但每个学生只会随机选择其中 条进行阅读,发布信息数量大于 条时,随机选择 条信息阅读。
请给出一种发布信息的方案,使得在期望条件下,有尽可能多的学生 阅读了对应的信息 。
数据范围
思路
- 从数据范围入手, 最多只有20个,尝试一下暴力,进行分类讨论
- 单独看每个信件被阅读到的期望贡献,答案就是 个信件期望相加,对于一个学生阅读信件数 来说,被期望阅读该信件,则该信件期望增加
- 在不考虑 的情况下,遍历每个学生,可以获得所有信件的期望,如果 能够确定,那么我们只需要取期望前 大的信件就是最优的。
- 如果 ,由上可知对于每个信件的期望分母一直变大,由于 ,所以随着 变大,最后期望变小,所以毫无意义。
- 现在考虑 ,由于随着 变大,尽管看似单个信件的期望在变小,信件数量增加,总期望变化不确定,而由于 最多只有 ,我们就直接暴力枚举 的情况,取最优解即可。
- 时间复杂度:
Solution
Round 118 (Rated for Div. 2)
D. MEX Sequences ( )
题意
给定长度 的数组 ,其中 询问合法子序列的个数,合法子序列的定义,对于这个序列的每一个前缀,最后一个数和前缀的 差值的绝对值不大于 。
答案 。
数据范围
思路
- 多画几次可以感觉出大概是个 状态机DP
- 合法序列的状态只有以下几种:
0 1 1 2 2 3 4 5
0 2 2 0 0 2 0 2
- 由第一种变为第二种
0 1 2 2 4 2 4 2 4
- DP阶段为从左往右的数组下标
- 状态表示:
f[i][0]
表示 MEX 为 状态为上述第一种的情况,f[i][1]
表示 MEX 为 状态为上述第二种的情况 - 状态转移: 设
i = a[i_]
f[i + 1][0] += f[i + 1][0] + f[i][0]
, 选或不选 + 递增连接。f[i + 1][1] += f[i + 1][1]
,在第二种情况选或不选if i > 0, f[i - 1][1] += f[i - 1][1] + f[i - 1][0]
,第二种情况选或不选 + 将第一种情况变成第二种情况
- 答案统计
Solution
Round 119 (Rated for Div. 2)
D. Exact Change ( )
题意
有 种货币,每个价值 元,给出 个商品的价值,每个价值为 ,询问最少的货币数能够准确买下所有商品
思路
- 此题毒瘤分类讨论,由于最大面值为 ,所以 元货币尽可能多,贪心地对最贵商品进行讨论,同时价值相同商品无意义排序去重。
- 设最大商品价值为
x
,对 模数讨论。 - 模数为 ,其他商品如果有模数为 或者 ,用一张 3 元 换成 1 + 2,可以凑出所有方案,否则答案为
x / 3
- 模数为 ,可以选择
x / 3 - 1
张 3 元 + 2 张 2 元或者x / 3
张 3 元 + 1 张 1 元,这是最少的答案为x / 3 + 1
- 对于前者,不能凑出价值 1 元 和 x - 1 元的商品
- 对于后者,不能凑出模数为 元的商品
- 所以如果上述两个情况同时成立,
ans++
- 模数为 ,最少的方案是
x / 3
张 3 元 + 1 张 2元 (x / 3 + 1
)。如果存在模数为 的商品,将一张 3 元拆成 1 + 2即可,ans++
Solution
E. Replace the Numbers ( )
题意
给一个数组初始为空,进行 次操作,一个是向数组末尾插数,一个是将数组中所有的 x
替换乘 y
数据范围
思路
- 模拟一下,发现每次将 向 连边,统计最终值就是看 连向的终点
- 换种说法,其实就是并查集的操作,而精妙在于如何处理中途插入
- 正难则反,倒着操作,遇见插入的时候就把
p[x]
放入答案,每次合并等于并查集合并p[x] = p[y]
- 最后将答案逆序输出,时间复杂度
Solution
Round 120 (Rated for Div. 2)
E. Math Test ( )
题意
有 个人做 道题,知道每个人做题的对错情况。每个人有一个预期得分 和实际得分 。 给定,而 是该人做对题目的分数之和。定义 “惊喜度” 为 每个人的 之和。
请你构造出一个每道题的分数方案,使得:
- 分数是一个 的排列。
- 在所有的方案中,该方案的 “惊喜度” 最大。
数据范围
思路
- 观察数据范围,,可以二进制枚举每个人的得分绝对值情况,拆绝对值
- 答案为
- 前半部分固定,想要答案最大,则后半部分的减数最小,那么对应答对次数小的题目应该获得更高的分数。
- 枚举不同
c[i]
情况,然后计算每个题目的答对次数(有负数),根据次数排序,从小到大赋值,更新答案即可。 - 这题时间复杂度比较玄学。按道理就是 ,却跑的挺快。
Solution
Round 125 (Rated for Div. 2)
E. Star MST ( )
题意
给了一张无向完全图,点数 和边权值范围 ,求合法图的数量 ,合法图的定义是,与 号点连接的所有边边权和是 的大小。
数据范围
思路
- 不难看出,主要核心是 1 号点,并且 1 号点连接的边的边权一定是最小的 个,否则不成立和为 ,很容易证明
- 由数据范围看出,应该是个 DP 题目,然后就开始玄学,可知非中心边的边权在
[中心边边权最大值,k]
范围内。 - DP阶段:加入图中的点数,方案数来源不同边的权值分配不同
- 状态表示: 根据最终答案是, 个点,边权最大值为 的方案,状态定义为
dp[i][j]
, 选了 个点,最大值为 方案数 - 考虑如何转移,每加入一个新点,会产生
i - 1
条边,加入i-z
个新点,其中新点定义不同对答案有贡献,贡献为 , 会产生(z-1) * (i-z) + (i-z) * (i-z-1) / 2
条新边。 - 第二维更新,从小到大遍历,
j
由j-1
转移,这样新产生的边不管是中心边还是非中心边,范围都在 之间 - 状态转移: ,答案为
dp[n][k]
- 时间复杂度:
Solution
Round 127 (Rated for Div. 2)
E. Preorder ( )
题意
给一颗节点数为 满二叉树,点权为小写字母,根为 , 可以交换每个节点的两颗子树,问最后对整个树来说会有多少种不同的先序遍历序列(字符串)。
思路
- 对于叶子节点,只有一种方案
- 对于非叶子节点,如果两个子树构成不同,该节点数方案为
2 * l * r
,否则为l * r
- 那么如何判断子树构成是否相同?
- 将所有子树调整为字典序最大或最小的情况,如
if(s[l] < s[r]) swap(s[l], s[r]), s[u] = " " + s[u] + s[l] + s[r]
。 - 然后做一次 DFS 即可求解
Solution
Div3/4
Round #748 div3
D2. Half of Same ( )
题意
D1的加强版,赛中过了,这里就不再单独将D1列出来。D1题意是输入一个数组 n$ 个元素 求出一个最大的整数 ,对每个元素减去若干个 之后,中所有元素相同。
此题(D2)的题意与D1大致相同,但求一个最大的 ,使得数组中至少一半的元素能够相同
思路
- 两道题答案所包含的元素组成的子数组中,设最小值为 ,不难发现,其他元素与的差值(设为 )一定都对 同余。(
应该这么表示吧?) - 由上一点可知, 一定是所有 的最大公约数。
- D1可以求出最小元素 ,再求其他元素相应的 ,D2需要观察数据范围,采用暴力枚举所有元素为 ,再筛选出其他满足条件的 ,存取所有 的约数,找出大于等于 的最大的那个。
自己想法
所有 同余想到了,还是没深入思考到 一定是所有 的最大公约数。
Solution
Round #780 div3
F2. Promising String ( )
题意
给了长度为 的字符串,由 '+' 和 '-' 组成,可以将字符串中两个 '+' 换成 1 个 '-',询问合法子串个数,合法子串定义,子串内 '+' 数量和 '-' 数量相同。
数据范围
思路
- F1 只有 3000,是一个暴力,F2考虑优化。
- 我们只关心区间中 '-' 个数与 '+' 个数的差值,自然 '+' 个数比 '-' 小,多模拟一下发现一个简单结论:区间中两数差值 时,区间合法。
- 因为是一个区间计数问题,我们可以考虑前缀和思想来做,如果两个前缀模 同余,那么两个前缀间的区间便合法。
- 对于这样的问题,由于需要统计 3 个模数的情况,并且不好用单一前缀和数组来统计小于
pre[i]
的所有合法前缀和,考虑用树状数组来处理 - 所以开 3 个树状数组,
tr[i]
表示模数为 的前缀和的树状数组,这样统计答案就很方便了。 - 由于做减法会有负数存在,树状数组只能存正数。所以需要值域整体右移,然后需要一点细节,具体看代码注释。
- 时间复杂度
Solution
Round #787 div3
F. Vlad and Unfinished Business ( )
题意
给了点数为 的树,和 个必须到达的点,出发的起点 和 到达终点 ,边权为 ,询问从起点经过指定的
个点,最后到达 的最短路径花费, 个点的访问顺序可以任意。
数据范围
思路
- 贪心地想,对于所有任务点必须到,然后要返回,那么起点到这些点的路径和至少为2倍到达这些点的花费。
- 问题转化为,经过 个点的"最小生成树",当然这里不需要最小生成树算法,只需要知道我们不需要经过的点数即可,剩余点数为 ,路径长度为 。
- 那么现在访问了所有点,要更贪心的想,从 我们是不是只用走一次就行了,先把 以外的点搜完,最后来搜 的子树即可,那么 只需要经过一次。
- 所以最后答案为 ,用 dfs 求子树标记的方式来解,详细见代码,时间复杂度
Solution
G. Sorting Pancakes ( )
题意
给了一个长度 的数组 ,和保证为 , 每次只能将 减 1, 加 1,询问最小的操作次数使 非严格递减。
数据范围
思路
- 毫无疑问,一道dp题,根据数据范围,大概可以容忍 级别的时空复杂度。
- 在设计状态前,务必需要一个结论:
- 对于这样的相邻移动元素的操作而言,设操作后的结果为 数组,总操作次数等于 ,对应前缀和差的绝对值的和
- 首先dp的阶段是长度 ,由于数组和固定,考虑加入一维当前数组的和 ,由于要满足递增或者递减,加入一维记录最后一个数 ,由于需要对比大小,这个数其实是一个最值。
- 那么状态已经设计出来了:
dp[i][j][k]
表示数组前 位,和为 ,最后一位最值为 的最小操作次数。 - 考虑如何转移方便,如果按照题意原本描述来看,转移方程是遍历前一个数
dp[i][j][k] = min(dp[i][j][k], dp[i - 1][j - k][x] + abs(j - s[i]))
,观察发现可以使用最小后缀来优化 的遍历,此时预处理最小后缀复杂度为 - 而考虑反着做,即将数组翻转后,考虑将数组构造成非严格递增。那么 代表的是最后一位的最大值。从小到大枚举 时,需要的是最小前缀,可以很方便的记录, 如下代码所示
- 时间复杂度:将 和 同级, ,翻转数组的方法还没有想到如何优化成 。
- 如果尝试采用记录后缀最小来优化,发现对于下标 上每个数不能超过
m / i
,否则它一定比前面的某个数大(平均值),加入循环条件中可以做到 。
- 如果尝试采用记录后缀最小来优化,发现对于下标 上每个数不能超过
Solution
Round #797 div3
D. Black and White Stripe ( )
固定长度最大子段和, 简单只贴代码了
Solution
E. Price Maximization ( )
双指针, 贪心, 排序, 或者 STL
题意
给了 个货品, 是偶数, 每个货品有价值 , 将货品两两配对, 两两配对和总价值为 , 给定 , 求 最大值
数据范围
思路
- 观察数据范围 , .
- 由于答案为重量之和向下取整, 对 来说, 无论怎样组合, 的贡献是确定的.
- 这样我们只用关心 的贡献, 贪心 地来想, 对于 , 需要找到满足最小余数
- 可以用两种方式实现
- 一种是显然的双指针 (
呵呵我写挂了, 很离谱, 有时间来补这个解法) - 还有一种是 jiangly超人 的 STL 做法(复杂度稍高但聊胜于无)
- 一种是显然的双指针 (
Solution
F. Shifting String ( )
置换, 环, 字符串最小循环节, LCM
题意
给定一个长度为 的字符串 , 和一个排列 , 每次操作让 , 询问至少经过多少次操作能让字符串与初始状态相同
数据范围
思路
- 草稿纸上画几遍, 发现可能与置换中所形成的各个环的长度有关系, 这个关系是各长度的
- 答案其实是与每个环经过多少次变换能变成原来的字符串, 由于是字符串关系, 这个多少次变换, 其实就是每个环上对应字符串的最小循环节.
- 所以答案就是各个环最小循环节长度的
- 如何求最小循环节? 此题可以暴力枚举循环节长度判断是否合法, 数据规模较大可以使用 KMP 求字符串最小循环节, 得到 数组判断
if(len % (len - ne[len]) == 0)
- 此处给出 KMP 的代码 (依然有些参考 jiangly的实现)
Solution
G. Count the Trains ( )
STL, 二分, 思维
题意
给了 个点, 每个点有值为 , 从左往右形成序列, 对于序列上下标 位置, 值为
有 次操作, 输入 , 每次操作对 a[k] -= d
, 询问每次操作完之后, 序列中有多少个不同的数 ?
思路
- 容易挖掘题目性质, 对于一个数 , 如果 , 那么 不会对答案产生贡献
- 由于答案是求不同的数个数 , 我们可以联想到
map, set
这一类 STL 容器来解决, 那么问题是如何实现. - 参照第一点, 我们尝试用
map<int,int>
容器来实现, 第一关键字为下标, 第二关键字为对应值 - 每次输入或操作对 map 中插入
i, a[i]
, 若前面迭代器元素值小于等于 则删除现在插入的迭代器, 若没有删除, 检查后面的迭代器是否满足要求(next(it)->second <= it->second
) - 实现过程中注意代码细节, 防止越界等错误, 时间复杂度为 , 参考 yyds的jiangly
Solution
野场
3000-3500 #932 9e 35 25
2600-2900 #E54 ed 55 46
2400-2500 #F87 ee 75 6e
2300 #FB5 f5 be 5e
2100-2200 #FA8 f7 cd 8a
1900-2000 #F9F f3 90 ff
1600-1800 #AAF ab a9 ff
1400-1500 #8DB 8d d9 ba
1200-1300 #9F7 95 fc 77
800-1200 #CCC cb cb cb
__EOF__

本文链接:https://www.cnblogs.com/Roshin/p/Codeforces_Solution.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具