五月杂题选做(part 2)
上回说到:2022.5 part 1
关于难度
可以秒杀的题。
思考一会儿后可以秒的题。
需要较长时间思考的题。
看题解、稍加指点就会做的题。
看题解后需要较长时间消化,甚至现在都没有完全理解的题。
ARC106D *1988
已知一个长度为 的序列 和一个数 ,对于所有 ,求
答案对 取模。
。
标签:组合。
直接二项式定理展开,推式子就好了。
可以发现是一个卷积,记 ,答案就可以直接卷积得到,暴力卷积即可,时间复杂度 。
ARC113D *1389
对于一个 的矩阵,每个元素都 ,定义 表示第 行的最小值, 表示第 列的最小值,已知 ,求有多少个不同的 ,答案对 取模。
。
标签:计数。
最简单的一个 ARC D,但还是想了一会儿的。
考虑一个很简单的东西,就是 这个东西可以很简单可以证明,然后可以发现,除非矩阵只有一行或一列,否则只要满足上面条件的 都可以凑出。
所以答案就简单了,枚举 ,那么 的贡献可以直接容斥,就是 ,直接算即可。
ARC112D *2028
有一个 的滑雪场,每次可以朝一个方向滑行,如果是冰则直接通过,直到到达一块地面或者撞到边缘停下,现在有一些地方已经是地面,求至少要把多少个冰改成地面可以使一个人从 出发可以到达所有点。
标签:模拟(?
考虑可以到达的点一定是一整行或者一整列的,然后一块地面就是可以从一行走到一列,那么可以直接并查集维护,最后的目标就是覆盖每一行或者每一列,直接找连通块个数即可。
ARC126D *2332
有一个长度为 的序列,每个元素都 ,每次可以交换两个数,问至少多少次操作后满足有一个连续子序列是 。
。
标签:dp。
显然直接状压 dp,如果选了一个数,那么对答案的贡献就是选的数的逆序对个数加上到目标位置的距离,目标位置显然是移动到中位数,直接做就好了。
ARC139D *2816
有一个长度为 的序列,进行 次操作,每次操作随机选择一个 的数加入序列,然后把序列中第 小的数删除,求所有方案最后序列中的数之和的和。
。
标签:计数。
神题,主要是因为题解看不懂,所以想了很久。
所有数的和可以转化为对于每个 ,计算有多少个数 即可。
开始时先找到 的左端点,然后考虑这个左端点的移动,先考虑开始时在 右边,那么如果放 ,那么位置不变,如果放 ,那么就左移动一格,在 左边同理。
那么直接枚举左端点最后移动到了哪里,直接计算方案数即可。
AGC021D *2287
定义一个字符串 的价值是它和它翻转后的串的最长公共子序列,现在已知一个串,进行最多 次修改操作,求修改后权值最大是多少。
。
标签:dp。
价值的定义显然是最长回文子序列。
所以可以直接区间 dp , 表示区间 修改 次的最大值,直接转移,时间复杂度 。
打了 ABC252,赛时过了 FG,由于是 unr 所以前面的题没做,Ex 想半天不会,寄。
但 psz 赛时不会 FG 我是真没想到。
ABC252G *2153
已知一个先序遍历,如果有多个儿子优先遍历编号小的,求有多少棵树满足这个先序遍历。
。
标签:dp。
显然直接来,可以发现一个区间要么是一棵树,要么是多棵树,分别开 dp 数组 ,直接每次在前面加入一棵树就好了。
ABC252Ex *3015
有 个珠子,每个珠子有一个颜色和价值,现在需要每种颜色的珠子各选一个,总价值就是所有珠子价值的异或和,求所有方案总价值第 大的价值是多少。
。
标签:搜索,字典树。
这个 有点离谱,因为不知道有啥算法是这个复杂度的。
考虑如果暴力搜索,那么复杂度就是 的最大值,根据 powerful number 的相关知识,可以发现这个东西复杂度是 。
然后直接 meet in the middle ,分成两部分,复杂度 ,把一半放到字典树上,然后查询第 大。
一个做法是二分,复杂度 爆炸。
有一个更好的做法,记录每个数在字典树上匹配哪一个节点,然后考虑这一位取什么,然后整体一起移动,这样复杂度 。
已知一个长度为 的数组 ,求有多少对 满足 。
。
标签:分块,卷积。
先把式子变一下,变成 ,那么考虑枚举 ,此时相当于找左右有多少个满足条件的,显然可以直接卷积,但复杂度 ,不如暴力。
考虑和暴力平衡一下复杂度,考虑分块,对于 都不在一块情况,直接对左右块进行卷积,然后中间统计答案即可。对于至少有一个和 在同一块的情况,可以直接开桶暴力算,总时间复杂度 ,FFT 常数比较大,适当把块长调大即可。
给定三个正整数 ,统计长度在 到 之间,元素大小都在 到 之间的单调不降序列的数量。输出答案对 取模的结果。
。
标签:组合,分治。
首先这个东西显然是一个插板法,考虑把每个数看成一个盒子,然后把数给放进去,可以得到答案是 ,然后相当于一个组合数前缀和,可以发现模数比较小,直接分治就好了。
定义一棵树是好的,当且仅当对于每个节点,它的左右儿子子树深度的差不超过 。问有多少棵 个节点的树是好的。
。
标签:dp。
考虑深度的范围, 表示深度为 的树的最小节点树, 表示最大节点树,那么可以发现
两个都是 级别的,所以最后的深度是 级别的。
然后直接来,设 表示 个点,深度为 的的方案数,转移的时候枚举左子树大小即可,时间复杂度 。
已知一个排列, 表示 到 有一条线段,需要把线段分成两个集合,使得这两个集合中的线段两两不交,求方案数,
。
标签:贪心。
线性做法,已经是 darkbzoj 上的最优解和最短解,目前没有找到另一种线性做法。
其实不是很难,考虑一个暴力做法,如果两条线段有交,那么就把这两条线段连一条边,最后相当于判断二分图方案数,这样暴力复杂度是 的。
考虑对于一个线段区间 没有一条边连向外面,那么可以发现这个区间形成一个独立的二分图,设二分图个数为 ,那么答案就是 。
现在只剩下判断无解的问题,也就是判断是否可以划分为两个集合,那么从左向右做,相当于两个上升子序列。
这个可以直接贪心,时间复杂度 。
有一个 的棋盘,要求每行至少放一个白棋,每列至少放一个黑棋,一个格子放棋子有一定代价,求最小代价。
。
标签:并查集。
这种棋盘问题一个经典的结论是考虑建出 个点然后进行连边,那么可以发现答案一定是一个基环树森林,那么直接贪心并查集维护就好了。
有 张牌,正反面都写着数字,现在可以把这些卡片任意翻转,使得正面的数字两两不同,得分为反面数字之和,求最大得分。
。
标签:贪心。
不错的题。
考虑直接连边,那么可以发现满足条件的联通块一定是树或者是基环树,直接贪心就好了。
定义运算 表示:如果 ,,否则, 。
已知两个序列 ,有 次询问,每次询问一个数 ,问有多少组 。
所有数据都 。
标签:卷积。
考虑如果是 ,那么显然是个卷积,但是这里有一个限制条件。
考虑分治,类似分治 fft,每次把 中的一个区间和 中一个更大的区间卷积,这样就可以了,减法也同理。
时间复杂度 。
CF1220F *2700
已知一个长度为 的排列,可以进行若干次循环移位,求多少次移位后得到的序列建出的笛卡尔树深度最小。
。
标签:单调栈,笛卡尔树。
有线段树做法,不过 too hard。
事实上直接来,考虑 左边和右边是两个不干扰的部分,因此左边做一下,右边做一下,然后直接合并即可,解决的问题变成加点,查询深度,这个可以在单调栈建笛卡尔树是顺便维护。
CF338E *2600
求 有多少长度为 的区 间中的数和 中的数完美匹配。两个数匹配当且仅当其和不小于 h。 (区间必须连续)
。
标签:线段树。
考虑先把 排序,那么可以和 中一个数匹配的一定是一段后缀,那么直接后缀加,可以发现满足条件需要满足 ,这样双指针和线段树维护即可。
CF724E *2900
题比较长,自己看吧。
标签:模拟网络流。
首先有一个网络流的做法就是建 个点然后暴力连 条边,直接爆炸,也没什么优化方法。
此时就有一种牛逼的算法:用 dp 模拟网络流。
考虑先变成最小割,然后就相当于要么割上面的,要么割下面的,如果割上面的还需要吧前面连过来的边都割了。
直接 dp,时间复杂度 。
CF722E *2900
有一个 的网格图,图中有 个特殊点。 初始时你有一个权值 ,并且只能向下或向右走, 每经过一个特殊点会使得你的权值/2(向上取整)。 求从 走到 时拥有权值的期望(mod )。
。
考虑每次除以 ,最多 次就变成 了,所以可以设 表示走到第 个关键点,经过了 个关键点的方案数。
然后直接来,从前面去转移,注意容斥一下就好了。
CF1209G2 *3200
题比较长,自己看吧
标签:线段树。
考虑一定是吧序列变成一段段区间,答案就是 减去每个区间众数之和, G1 不带修,直接模拟就好了。
考虑用 set 去记录每个数出现的位置,然后区间加,那么相当于 的位置就是断点,分开两个连续段。
每个数都直接在左端点放入出现的位置,然后去查询最大值,这样只需要比较左右的最小值就可以判断两区间合并时的情况。
具体而言,如果维护断点复杂度会爆炸,但是可以维护区间最小值,把最小值当做是断点,这样就可以轻松维护了。
CF472G *2800
题比较长,自己看吧。
标签:多项式,卷积,分块。
显然这个匹配可以写成一个卷积形式,但是是区间求和,很不好搞。
常见套路是直接分块,块内的和就可以直接维护了,本题需要一定的卡常技巧。
CF1553F *2300
已知一个序列 ,定义 表示
对于每个 ,求出 。
。
标签:树状数组。
考虑递推,那么相当于要计算
右边那个开桶,然后调和级数算,相当于单点加,区间查,直接树状数组。
左边的考虑一个数对后面的贡献,也就是区间加,单点查,也可以树状数组。
CF1615G *3300
给定一个数列 ,你需要将所有 的位置填上一个 的正整数,使得数列的「值」最大。
数列的值定义为满足以下条件的 的个数:
- 存在 ,使得 。
输出值最大的序列,若有多解,输出任意一个。
。
标签:一般图最大匹配。
考虑填数的这些 的连续段进行讨论。
如果连续段长度为奇数,那么必然是填 个相同数,然后剩下一个和左右的进行匹配。
如果连续段长度为偶数,那么就有两种情况,要么是填 个相同数,要么左右各匹配一个然后填 个数。
与左右匹配可以看成是一半图最大匹配,先对不同的数值建点。
- 如果是奇数,新建一个点,向左右的数连边。
- 如果是偶数,新建两个点,分别向左右连边,然后这两个点连边。
然后直接跑最大匹配,带花树会寄,用随机匹配。
随机匹配也就是把边随机顺序然后跑二分图,不过输出方案比较恶心。
CF1615F *2800
对于两个长度为 的 串 ,你可以对 进行两种操作:把相邻两个 变成 或把相邻两个 变成 ,定义 到 的距离为最少操作次数使得 变成 ,如过没法变则距离为 。
现在你有两个不完整的字符串,可以把其中的 变成 或 ,求所有情况所得到的两个 串的距离之和。
。
标签:dp。
不错的题。
考虑把相邻两个相同的翻转很难搞,因为甚至是否有解也判断不了,所以考虑把所有奇数位置上的东西翻转,这样变成翻转相邻两个不同的,也就是交换相邻两个元素。
那么距离就是把所有 的位置排序后对应元素差的绝对值了。
考虑 dp 设 表示已经做完了 ,前面 中的 的个数比 多 个的方案数,那么统计 这个部分对答案的贡献,也就是 ,转移可以直接转移。
ARC102E *2484
有 个 面骰子,求对于每个 ,求出有多少种骰子方案使得没有两个骰子上的数加起来等于 。
。
标签:组合计数。
考虑对于一个 ,把所有数分成三类
- 可以乱选。
- 是偶数,,最多选 个。
- 其他情况,把 分成一组,一组中只可以选其中一个。
直接计数即可。
打了 ABC253,开局秒了E,然后会了F,psz 给了我 ABCD,F 写了一会儿就过了,发现 G 是 sb 题,类似直接分块然后就好了,但细节很多,psz 去写,我先看 Ex,然后发现会了,找了 10min 矩阵树板子,终于找到了(还不如重写一遍),然后直接冲了一波,WA 了一下,结果发现是没取模。。。然后直接过了。
接下来帮 psz 调 G,然后过了。
第一次 AK ABC,非常开心,总用时 78 分钟。
ABC253Ex *2758
有 个点, 条边,每次随机加一条边(可以重复加),对于每个 ,求出有多少概率满足加入 条边后图是一个森林,答案对 取模。
。
标签:矩阵树定理,状压 dp。
考虑枚举森林是怎么样的,然后假设里面有 条边,概率就是 。
那么最后的森林是怎么样的呢?直接枚举一个连通块,求出这个连通块是一棵树的方案数,也就是生成树计数,直接矩阵树定理。
然后状压 dp 合并,统计答案即可,时间复杂度 。
打 ARC141,晚 分钟进场,unr,输麻了。
psz 过 A 之后去看注意开发表重要讲话,笑不活了,直接摆烂。
开局我直接冲 D。
这个 的条件明显是拿来匹配的,然后直接按 的幂次分类即可,但是发现寄了。
那就按去掉 之后的部分分类,可以发现每一个部分最多选一个,最多有 个部分,可以判断无解。
所以就是每个部分选一个,按倍数关系建拓扑图,然后考虑一个点选 的幂次。
显然,如果 是 的幂次,那么 乘上 的幂次一定小于 ,满足拓扑顺序。
想要满足条件,一个点选的幂次一定是一段区间,正反跑两边拓扑排序即可。
观察仔细,你会发现提交时间是 《2022-05-29 22:02:23》,是的,我差 2min 场切 *2800+,悲。
ARC141E *3009
有 个点,每个点被表示为 ,有 次操作,每次操作把所有 ,将 向 连边。
。
标签:并查集。
首先按 把点分类,那么可以发现操作时机上就是两个组中的点对应连边。
如果这两组一开始不是一个连通块,那么直接连通块个数减少 。
否则,计算这两个联通块的距离,然后相当于求个 即可。
这些都可以用并查集维护,然后就没了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效