欢迎光临散文网 会员登陆 & 注册

复盘|第349场周赛

2023-06-12 13:16 作者:UCLmsc  | 我要投稿

既不是最小值也不是最大值

【排序】前三个元素排序取中间的,当元素个数<=2时不存在。

执行子串操作后的字典序最小字符串

【贪心】据题意,把a替换成z会让字典序变大,所以目标子串里不应包含a,其他字母都可以替换。从左到右找到第一个不等于a的字符s[i],冰箱后不断不断减一,直到s末尾或遇到a。特判s全a的情况,此时把最后一个a改为z。

收集巧克力

【枚举】如果不操作,第i个巧克力必须花费nums[i]收集,总成本为所有nums[i]之和。如果操作一次,第i个巧克力可以花费min(nums[i], nums[(i+1) mod n], nums[(i+1) mod n])收集,如果操作两次,第i个巧克力可以花费min(nums[i], nums[(i+1) mod n], nums[(i + 2) mod n])收集。暴力枚举需要O(n^3),可以用一个长为n的数组sm统计操作i次的总花费,这样就可以一边枚举子数组,一边求最小值,一边累加花费了。

最大和查询

【排序 + 单调栈 + 二分】先把nums1和询问中的x_i排序,按照x_i从大到小,nums1[j]从大到小的顺序处理,同时增量地维护nums1[j]≥x_i的nums2[j]。如果nums2[j]比之前遍历过的nums2[j']小,由于nums1[j]从大到小处理的,所以nums1[j]+nums2[j]也比之前遍历过的nums1[j']+nums2[j']小;如果相等,无需考虑;如果大于,可以入栈。如果nums1[j+nums2[j]不低于栈顶的nums1[j']+nums2[j'],那么可以弹出栈顶。因为更大的nums2[j]更能满足≥y_i的要求,栈顶的nums1[j]+nums2[j]在后续的询问中,永远不会是最大值。代码实现时,可以直接比较nums1[j]+nums2[j]与栈顶的值,这是因为如果这一条件成立,由于nums1[j]是从大到小处理的,nums1[j]+nums2[j]能比栈顶的大,说明nums2[j]必然不低于栈顶的nums2[j']。这样会得到一个从栈底到栈顶,nums2[j]递增,nums[j]+nums2[j]递减的单调栈。最后在单调栈中二分≥的最小的num2[j],对应的nums1[j]+nums2[j]就是最大的。

【动态开点线段树】按照查询的y_i的大小排序,从后往前处理每个查询,对于每个查询,需要找到所有comb[j] [0] + comb[j] [1]的最大值。用线段树维护这个信息,用线段树的每个节点表示一个区间[l, r],节点的值表示所有满足comb[j] [1]属于区间comb[j] [0] + comb[j] [1]的最大值,对于每个查询,将所有满足comb[j] [0]>= x_i的comb[j] [1]插入线段树,然后查询区间[y_i, MX]的最大值。


复盘|第349场周赛的评论 (共 条)

分享到微博请遵守国家法律