Loading

AT 题目讲解

cy 让我讲的,必须得要有一个博客啊。

写代码?那是绝对不可以的。

[ABC194E] Mex Min

Subtask 1

暴力都会吧。

枚举以 \(i\) 开头的长度为 \(m\) 的子序列,然后 \(i \sim i + m - 1\) 扫一遍,用一个桶记录一遍,即可求出 \(\text{mex}\) 值。

时间复杂度:\(O(n^2)\)

Subtask 2

注意:仅限个人思路(口胡),可能不太正确。

考虑 \(\text{mex}\) 的本质是什么,是第一段连续区间的最大值 $ + 1$( \([-1, -1]\) 也算单独一段),所以我们考虑把他们维护一个差值,然后用线段树维护一下就行(维护连续为 \(1\) 的段,注意要特判不从 \(0\) 开始的)。

注意这种做法只有再 \(a\) 是有序的情况下才能做到以下复杂度。

时间复杂度:\(O(n \log_2 n)\)

感觉卡卡能过去。

Subtask 3

开始牛逼的正解。

答:是我最不擅长的单调队列。

我们考虑维护一个单调队列(其实不是原汁原味的),或者说是维护一段长度为 \(m\) 的区间,考虑删除一个数,再加进来一个数,能否产生变化。

时间复杂度:\(O(n)\)

Subtask 4

如果感觉自己很牛逼的可以进来看一看:

考虑可以回滚莫队去做。由于莫队 \(\text{mex}\) 只支持删除更新,所以我们使用回滚莫队,让它只删除(你会发现根本跑不满)。

时间复杂度:\(O(n \sqrt n)\)

然后下面还介绍一种思路:

线段树上二分。

[ABC195D] Shipping Center

贪心题吗,就是乱贪。

Subtask 1

最原始的暴力算法。

直接爆搜箱子全排列把的箱子给这 \(n\) 个人匹配。

时间复杂度:\(O(?)\)

Subtask 2

有没有一种感觉,这个题像 DP。

考虑状压:

\(f_{i, j}\) 为行李使用状况的集合和盒子使用状况的集合(\(1\) 表示用过,\(0\) 表示没用过),然后你暴力枚举之前是用得哪一个盒子和哪一个行李就 OK 了。注意到 \(i\)\(j\) 二进制里 \(1\) 的个数应该是相等的,所以可以优化避免冗余状态。

时间复杂度:\(O(2^n 2^m n m)\)

也就比爆搜快了一点而已。

Subtask 3

有一句古话是这么说的:你往往没有思路的题都是贪心。

所以我们贪心。

考虑最小的盒子一定要装尽量大的价值,考虑感性证明:

尽量小的盒子如果装尽量大的价值,那么必然之后就会多出一个物品的贡献(因为如果不用小盒子装肯定是用大盒子装),肯定是不劣的。

然后我们把价值从大到小排序,盒子容量从小到大排序,就 OK 了。

然后一个一个物品用盒子去匹配就好了。

时间复杂度:\(O(qn \log_2 n)\)

[ABC204D] Cooking

Subtask 1

真没想到什么暴力,如果有暴力,可以提出来。

考虑最终答案是什么:

其实就是两个烤箱中消耗时间最长的那一个烤箱的时间。

所以这道题的目标是让我们让时间最小的那个烤箱时间尽可能长(因为时长是固定的,要做到尽可能平均),所以我们可以设 DP 状态 \(f_{i}\) 表示在不超过这么多时间内,做菜时间最长是多少。

然后由于每个菜只有一道,就可以 01 背包去搞了。其实上面那个状态是滚动数组优化过的。

[ABC205D] Kth Excluded

Subtask 1

直接枚举就行了。复杂度直接升天。

Subtask 2

不难发现这道题的 \(a\) 是有序的,所以我们可以往单调性这一块方面想(其实出现第 \(k\) 小这种字眼都可以往单调性去想)。

又是第 \(k\) 小,所以不难想到可以二分去做。

我们定义 \(f_i\)\(1 \sim i\) 不同于 \(a_i\) 正整数个数,不难发现这个数组是单调不减的。

考虑 \(f_i = i - g_i\)\(g_i\)\(a\) 数组中不超过 \(i\) 的数有多少个,可以 \(\text{map}\) + 前缀和(二分是最好的)去搞(当然你用动态开点权值线段树我也没意见)。

时间复杂度:好一点是 \(O(n + \log_2 10^{18})\),不好就是 \(\log_2^2\) 了,其实没多大差别。

posted @ 2023-06-02 11:56  Alexande  阅读(22)  评论(0)    收藏  举报