AGC028
cnblogs
A (\texttt{Easy} \ 2 / 0)
答案只有可能为
B (\texttt{Easy} \ 2 / 0)
一个区间
发现这只与长度有关,于是枚举长度并计算即可,注意特判
时间复杂度
C (\texttt{Easy} \ 3 / 1)
降智了很久。
首先把
- 存在
11, 00 。 - 全部为
10 或全部为01 。
第二种情况是容易的。对于第一种情况,我们不妨考虑最小值的下界:所有的
- 若第
n + 1 个数的位置和第n 个数的位置不一样,则答案为前n - 1 个数和第n + 1 个数之和。 - 否则,第
n - 1 个数和第n + 1 个数位置不一样、第n 个数和第n + 2 个数的位置也不一样,取差较小的那一对替换即可。
时间复杂度
D (\texttt{Easy} \ 3 / 3)
很久以前做看了题解,差不多忘了但是现在胡出来了系列。
设
时间复杂度
E (\texttt{Hard} \ 7 / 3)
非常厉害的贪心题。
我们考虑逐位决定,问题转化为一个前缀已经划分好了,判定剩下的数是否存在一种划分方案满足要求。
我们称原序列中的前缀最大值为「大的」,其余数为「小的」,则有如下结论:
- 若存在满足条件的划分方案,则必然存在一种方案,使得
X 和Y 中至少存在一个序列,使得剩下的数中被划分到该序列并在这个序列中作为前缀最大值的数全部是大的。
证明:考虑反证法。假设结论不成立,则对于任意一种方案,选取剩下的小的数中被划分到
X, Y 并作为前缀最大值的数各一个,记作x, y ,则把x 放到Y 中,并把y 放到X 中,不难发现二者都不再是前缀最大值了,所以两个序列的前缀最大值个数都减少了1 ,依然相等。一直调整下去,可以得到一种满足结论的方案。
不妨假设
移项可得
左边的数是确定的;右边的
于是我们把问题转为了如下形式:
- 有一个排列,每个点的权值为
1 或2 ,每次询问一个后缀中能否找出首项> k 并且权值和为s 的递增子序列。询问的后缀长度递减。
发现存在权值和为
这个可以 dp 解决,dp 的过程可以用线段树优化,这部分并不难,不再赘述。
总的时间复杂度是
F (\texttt{Medium} \ 6 / 2)
不知道怎么想到的,F2 不会,
我们首先维护出
怎么办呢?我们从下往上、从右往左地计算答案,每次计算完一个点,如果它的左边和上边都不是数字,就意味着它不可能再被计算了,可以直接删去它并更新前缀和。删去之后可能会出现新的点满足左边和上边都不是数字,递归删除即可。这样我们在计算一个点的答案时,
时间复杂度
以下是 F2 的一些卡常技巧:
- 大部分数组,例如
L, R 还有存储前缀和的数组,都可以开成short。 - 递归删除的过程写手工栈。注意栈的大小超过了
short的范围。 - 如果
(i, j) 并不能走到第k 行,就可以直接break掉了。 - 交换前缀和数组的两维,使得内存访问连续。
使用这四个技巧之后可以卡到