【题解】2025牛客寒假算法基础集训营4

A. Tokitsukaze and Absolute Expectation

根据期望的线性性质,可以转化成求 的期望之和。那么问题就转化成了 的期望。

分母显然,由于 在区间 等概率随机,所以分母为

分子是 绝对值之差的所有情况之和。假设目前计算的是 , 。设 为这两个区间的交,即 , 。然后通过下面 3 个部分进行计算:

情况 1 和情况 2 很好算,因为它们区间都没有交。实现可以参考代码中的 cal2 函数。

情况 3 因为它是对称的,可以推出一个式子。式子可以参考代码中的 cal3 函数。

求完分子就做完了。

由于每次需要求一下分母的逆元,所以时间复杂度为 ,

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401049

B. Tokitsukaze and Balance String (easy)

按题意模拟,直接暴力。时间复杂度

需要注意的是,把 ? 填了之后,回溯的时候要填回 ?,不然下一次递归到这一层,这里就不是 ?,就错了。

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401057

C. Tokitsukaze and Balance String (hard)

对于长度为 的01字符串 ,发现当 相等时 "01" 与 "10" 子串数量相等。所以 中的 ? 可以随便填,不会影响 "01" 与 "10" 子串数量。

中的 ? 个数为

先不考虑 ? 的情况。

如果 中的 可以随意翻转,即 。所以贡献为

如果 ,则必须翻转 或者 ,即 。所以贡献为

至于 ? 的情况,可以再分类讨论一下。具体参考代码。

由于 最多等于 ,所以我们可以预处理一下 的幂,不需要用快速幂,时间复杂度为

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401063

D. Tokitsukaze and Concatenate Palindrome

贪心。考虑按某种顺序将回文两侧尽可能匹配上。

先让 匹配。如果 ,直接做完了。

否则肯定是一长一短,长的那个字符串会跨过回文中心,所以再自己匹配自己一下,把回文中心的部分匹配完。注意不要多匹配。

剩下的就是不能匹配的,直接数一下有多少个然后除二即可。如果有奇数个无法匹配的。那么 肯定为奇数;否则肯定是偶数个无法匹配的,因为每次成功匹配都会使字符同时减少两个。所以直接除二就行。

单组时间复杂度 ,如果把清空数组的时间复杂度算进去就是

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401069

E. Tokitsukaze and Dragon's Breath

观察斜线的下标可以发现,每条斜线要么 是固定的,要么 是固定的。

于是可以用两个 map 记录所有 的和,然后枚举 'X' 的中点计算答案。

也可以不用 map,用数组,但需要加上一个偏移量来保证 不是负数。

用数组实现的时间复杂度为

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401073

F. Tokitsukaze and Kth Problem (easy)

Solution 1:二分答案

这类求第 k 大,或者前 k 大类的题,一般可以先考虑二分答案。

由于 easy 版本与序列顺序无关,所以可以先 sort,然后二分答案后用双指针数一下有多少对大于等于答案。

求出第 k 大后,大于答案的对可以暴力求出来,剩下的再用答案填。

时间复杂度 , 为值域。

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401127

Solution 2:堆

我们可以构造一种方案,使得堆内必定存在当前的最大值。这样只要从堆中弹出 次就是前 k 大。

对于这道题,可以枚举 ,对于每个 ,找到与它匹配能使 最大的 放入堆中。

每次从堆中弹出一个东西,我们就把下一个与 匹配的 放入堆中(如果有的话)。

时间复杂度

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401133

G. Tokitsukaze and Kth Problem (hard)

本题沿用 easy 版本 Solution 2 的做法。

现在的问题就是无法对原数组进行排序后二分找匹配的

由于 ,我们可以将 的值分为两类。一类是 ,另一类是

对于第一类,我们需要实现的功能是:查询区间内小于 的最大的数;对于第二类,只需要找到 的最大值即可。

第二类很好解决,主要是第一类,问题转化成如何查询区间内小于 的最大的数,没有修改。

std 的做法是建立一个线段树,每个节点用一个 vector 存放区间内的所有数。对于查询,找到这个区间对应的 个节点,然后在节点对应的 vector 内二分查找小于 的最大的数,然后把这些节点的结果求个最大值。

在建立线段树的时候可以使用归并排序实现,时间复杂度为 。但时间复杂度的瓶颈不在建树,查询时需要找到区间对应的 个节点,然后需要在每个节点的 vector 内二分,所以总时间复杂度是

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401076

Bonus

上面分成的两类,发现选择第一类是优于选择第二类的。然后第一类内部是单调的,第二类内部也是单调的,并且第一类与第二类没有交。所以可以先求出符合第一类的数的个数,然后用 kth 求出值;第一类用完后,再开始使用第二类,同样的也是用 kth 求出值。这样可以用主席树来做,时间复杂度

H. Tokitsukaze and Necklace

显然是一个 dp 题。

表示当前使用了 a b c,上两个字符为 ,上一个字符为 的最大喜爱值。

转移的话很简单,就枚举当前填哪个字母,然后根据前两个字母和当前的字母计算贡献。注意填的每种字母数量不能超过给定的数量。

然后它是个环,所以需要断环成链,即枚举第一个字符和第二个字符填什么。

输出方案只需要在转移时记录一下上一个字符是什么,具体参考代码。

时间复杂度 。你可以写一个暴力枚举一下 最大是多少,发现最大的情况是 。所以时间复杂度为 。空间复杂度是

思路简单,写起来繁琐,还容易写挂,而且还容易爆空间。

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401080

I. Tokitsukaze and Pajama Party

签到题。考察选手是否掌握循环语句,以及时间复杂度计算。

每次碰到 "uwawauwa" 子串时,假设最开头的 'u' 的下标是 ,只需要统计 中有多少个 'u',累加就是答案。

如果每次都遍历 ,时间复杂度为 ,无法接受。我们可以用一个变量来维护即可 'u' 的个数。时间复杂度

需要注意的是,"uwawa" 最多有 个,大致估算一下最终答案不会超过 int,所以不需要开 long long 也能通过。

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401083

J. Tokitsukaze and Recall

题目要求访问到的点数最多,并且访问顺序的字典序最小。

先解决点数最多的问题。求出每个连通块有多少个点,并按点的数量从大到小排序。这样肯定优先选择点数前 多的连通块;如果 大于等于连通块个数,可以全选。

再考虑字典序最小。首先在选连通块时,如果两个连通块的点数相同但只能选一个的时候,需要做一个选择。设连通块内编号最小的节点的编号为 ,在排序时,优先选择 小的那个连通块。

统计连通块内节点个数与最小编号可以建图后 dfs 或者并查集实现。

为了使字典序最小,我们用一个优先队列来维护所有可访问的节点,每次弹出最小编号。

因为要求访问顺序字典序最小,所以仲裁者肯定会被部署在一个连通块的编号最小的节点上,也就是部署在连通块的 节点。所以最初,把所有选择的连通块的 节点都放入优先队列。

然后要注意,如果 大于连通块个数,或者换句话说, 还有剩余,可以把剩余的 服务于最小字典序。具体的,如果当前 ,并且存在编号比队列弹出来的编号更小的节点,那么直接在那个节点上部署是更优的。

由于使用了优先队列,每个节点最多会入队出队一次,所以时间复杂度

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401084

K. Tokitsukaze and Shawarma

签到题,输出

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401086

L. Tokitsukaze and XOR-Triangle

如果求的是 ,那就是个大家都会的经典原题。但现在求的是 。直接做不好做,考虑把它拆解一下。

先看后一半 ,这两个区间没有相交,所以可以转化成类似 的求法。即拆位后统计 中这一位上有多少个 ;再统计 中这一位上有多少个 ,然后乘一乘。

再看前一半 。这一部分可以预处理出对于每个 。然后记 ,那么

然后就做完了。时间复杂度 是值域

代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=75401087

全部评论
L题那个经典原题在哪儿啊,不太能看懂代码
5 回复 分享
发布于 02-07 18:28 河南
为什么这次没有评级?/yiw
点赞 回复 分享
发布于 02-07 11:34 江西
tql!%%%
点赞 回复 分享
发布于 02-07 11:32 江西
A题为啥区间相同的时候就返回(r-l+1)*(r-l)*(r-l+2)/3就行?有证明吗,我听别人说这是平方和,但是好像和(2*n+1)*n*(n+1)/6也不太像,本人观察力不佳,求指教
点赞 回复 分享
发布于 02-07 01:29 福建

相关推荐

03-24 16:56
已编辑
肇庆学院 后端
一天代码十万三:你看看人家进大厂的简历就知道了,你这个学历得acm+大厂实习+熟悉底层+运气很好 才有可能进某个大厂,因为大部分是直接卡学历的
投递快手等公司10个岗位
点赞 评论 收藏
分享
评论
13
3
分享

创作者周榜

更多
牛客网
牛客企业服务