风起水起难靠岸
1.Majority
好题啊。
首先发现操作比较复杂,但是有递归性,我们可以只研究最后一次操作。
然后令 表示长度为 的合法串的方案数,转移的时候枚举两段和中间,前缀和优化一下。
然后发现会算重,因为 这样的串,最后一步可以是 或者 变化而来。
我们想要去重,就可以让操作唯一。
操作唯一可以在从左往右扫的时候,能合并就合并。
这样的话, 其实不太好设计状态,在一个合并过程中的串是比较复杂的。
总之我们想多记录一维,因为还是考虑最后一次合并,最后一次合并形如 合并成全是 。
因此考虑记录一维,代表前缀 的个数,并且能遵循能合并就合并。
具体来说 表示长度为 ,合并后前缀 的个数是 的方案数。
然后考虑转移。
从 或者 转移过来都不是特别好办。
然后手玩一下,发现可以从 和后面一段 ,再一段串拼接而来。
这里满足 ,因为得满足不能合并。
这个限制使得我们可以用一个前缀和轻易维护。
时间复杂度:。
2.Bracket Cost
先考虑固定 的时候,贡献是什么样子的。
首先令这个区间内左括号的个数为 ,右括号的个数为 。
首先需要 满足括号个数配对好。
其次新加入的时候,肯定能配对好,原来的形态里如果有 对配对好的,那么最后还有 对是肯定需要调整的。
下界因此就是 。
然后上界显然也是,因为每一次操作一定能使得匹配数 。
考虑这个怎么计算。
先看 ,如果在 中一对括号匹配,那么在原串中也一定匹配,反之亦然。
所以对于 两个位置匹配,贡献就是 。
然后 考虑拆开。
先有 ,因为 是好求的,凑这个形式。
因此 。
这些都是好算的,,其中 是前缀和。
绝对值就先排序再处理就可以了。
时间复杂度:。
3.Count Sequences
考虑原数组的差分数组,对 取模之后每个数只能为 。
考虑枚举 的个数 , 的个数显然是 。
枚举 对 取模的余数,然后考虑任意一个形态,从某个位置往后以 为单位的平移依然是合法的。
所以剩下计算一下 的个数,直接插板即可。
时间复杂度:。
4.No Smoking!
扫描线。
维护一个 来存当前的线段,这些线段一定是能按照函数值排序的,而且不会发生错乱,否则一定有交。
因此在每一条线段插入的时候,考虑和 中上一个和下一个判一判是否相交即可。
删除的时候也要判!!!
判 。
对于 的线段,有一个巧妙的处理方法是所有线段随机偏转一个小角度,规避特判。
时间复杂度:
5.Two Professors
不考虑 和 的情况,可以有一个贪心做法。
按左端点排序,拿一个 来维护当前的所有进程的右端点。
这样某条线段插入的时候,所有能放的进程在后面都是等价的,随便放一个,更新 即可。
这个贪心的正确性显然。
设这样做出来的答案为 。
那么真实答案只能是 或者 。
取决于是否存在一种方案,使得答案是 , 和 不放在一起。
假设 的左端点在 ,前面,否则可以 。
注意到,如果一个进程放进去的时候,如果有多个选择,其中一个选择是 的话,那么就可以将这些行,后面的部分全部调换。
所以这样就是能做到 ,否则如果放入 那一行的所有决策唯一,而且 也在,就只能 。
时间复杂度:
6.Construct a Matrix
和 的询问是独立的。
的询问其实是限制了区间内 个数的奇偶性。
把 和 的询问区间覆盖之后,其他全部填 即可。
剩下的可以形如一些方程,每个方程用前缀和可以改成 个未知数。
也就是 个元, 个方程的异或方程组, 优化即可。
最后填回去,注意到如果有一个地方,应该填 ,但是又和前面 的冲突了,填 没有影响,后面的前缀和关于这个的更改是抵消掉的。
时间复杂度:
7.Telegraph
首先如果确定了所有选的点的 ,那么和 应该是大的对大的,小的对小的。
所以考虑从小到大枚举 ,然后选,这一步其实挺自然的,但是我没想到,一直在树型结构上想。
考虑 表示考虑当前层是 ,已经匹配了 前 大,当前层有 个,上一层有 个。
其中 都是没被选, 都是已经生成过左儿子,没生成右儿子,没被选的。
保留 的意义在于可以生成下一层的点。
考虑换一种计算贡献的方式,每一次换层的时候,都把加上还没选的 总和,这样显然正确。
因此就有
转移和 无关,可以忽略掉 吗,答案是肯定的。
因为取答案的时候和 无关,转移的时候也不会出现环。
固定住 ,按 分层的时候第一种转移是换层的,第二层是 不递减的转移。
因此直接写成 这个取到最优的时候, 也是唯一固定的,而且不需要考虑 相关的事情。
滚动掉 ,把空间做到 即可通过。
时间复杂度:。
8.Substring Restrictions
每次操作发现就是把 和 对应的位置并查集合并起来。
考虑优化这个过程。
下一步感觉挺套路的,但我不是很会,入门的时候倍增就没学好。
并查集这种可以结合的,重复贡献不影响结果的,可以用类似 表的那种办法倍增拆成两个区间,把这一层分成 组合并起来。
然后就是跑 层,每一层合并完之后还传到下面去,对于每一个 ,如果 ,那么就把下一层中 合并 合并。
可以证明每一层合并到下面的边数都是 的。
时间复杂度:
9.Max Intersection Partition
首先考虑 做法。
设计一个 表示前 个线段,已经分成了 段的最大值。
然后因为这样连续选一段区间需要排序,所以想怎么排序。
发现怎么排序都不可以处理包含的关系,所以考虑特殊处理包含关系。
如果 包含 ,那么 要么自成一段,要么在别的段都是添乱的,可以直接放到 这一段来。
这样我们就可以在 的时候忽略这样的 。
然后 就很好做了,所有左端点递增,右端点递增。
的过程可能需要贡献和 取 ,但是如果这种情况,说明有的段是 ,那么更优的一种方案是取最大的 条自成一段,其余放一起,这种特判。
所以不需要考虑取 ,总是 即可。
接着考虑如果分成了若干段,那么贡献是形如 。
进而发现每个断点的贡献都是独立的,和包含其他的段一起选 个最大的即可。
时间复杂度:
10.MST and Rectangles
看到 MST 题的基本做法就是分析一下问题,然后套用三个最小生成树算法。
Boruvka 的拓展性是最强的,本题也就是用 Boruvka。
首先一条边 的代价是 ,我们可以另外维护一个矩形 ,满足 。
这样 的代价直接就是 。
对于一个操作,对于若干的 同时加上 ,其实可以看作 和 同时加上 ,也就是两次矩形加。
Boruvka 的流程是,每一轮把所有连通块向外的最短边找出来连接,每一轮连通块个数至少除以 ,共 轮。
找最短边考虑每一轮离线+扫描线,从左往右扫的时候,遇到一些操作,先把操作用来更新线段树上维护的信息。
扫描线的下标是当前考虑向外连的节点,线段树的下标是其他的点。
对于每一个点,需要考虑向外连接的最小边,也就是线段树上的最小值,由于可能会在同一个连通块内,所以维护两个颜色不同的即可。
对于一段 都没有操作,那么 的最小边应该和 相同。
时间复杂度:
空间复杂度:
11.Monster
首先发现,如果想要花费 的代价,你可以覆盖尽量多,具体来说就是直到左边和右边第一个代价大于 的位置。
这样构建出一个树形结构,并且恰好是笛卡尔树。
改写一下限制,形如:
第 号节点,在笛卡尔树上到根的路径中要选至少 次,在 选一次的代价是 。
笛卡尔树上面的 要比下面的大。
因此我们可以想一些贪心。
在 节点,先选 次 ,然后这么做可以让儿子里的少选,然后还可以多选几次 ,直到再选 是亏的。
维护若干个二元组形如 表示 代价为 的要选 次,考虑在当前多选一次 ,花费是 ,正向的贡献是所有 的 求和。
把所有的 按照顺序维护,一直选 ,直到某个 之后选 是不划算的。
考虑复杂度,如果用一个数据结构维护 ,再启发式合并,就是 。
每个 会贡献一对新的 ,且这一对 最多会被删除一次。
然后这么做会发现可能对于一个 已经被父亲 覆盖,对于一个 作为 的父亲,替换一次 之后会把 的贡献再算一次。
这种情况就可以把 维护出一种树形结构,先忽略 , 的删完再把 的贡献还原进去。
这个树形结构可以不显式建出来,魔改一下二元组的意义即可。
12.清风
考虑倒着做,最终答案的形态可以分成若干段 的。
的容易做,令 表示答案,转移枚举最后一次放的是谁。
这个可以分治ntt算。
后面是一个背包,考虑对白色格子的个数背包而不是黑色格子,这样填一个白色前面可以带若干个黑色,多项式 即可。
时间复杂度:
然而原题的模数是 ,所以得考虑组合意义做法。
考虑添加一个 ,然后连成一个环,每次视作从一个位置出发,顺时针或者逆时针出发,到第一个白色格子染黑。
这个和原问题其实是等价的,因为如果一个选到了 的决策一定是黑色的,那么被当做不合法的方案。
这样一来,每个格子被染黑的 “概率” 其实是相等的。
因此答案就是 。
13.半夜
的做法是显然的,把 变成 ,从每一个位置出发做一次 的 求 即可。
进一步数形结合发现这个 的轮廓线是具有单调性的。
分治做决策单调性即可。
感觉很智慧,也可能比较套路,值得学习。
14.鸣蝉
多个线段并这种事情很逆天,所以基本上不太有简单做法。
考虑暴力,用 来维护不同的颜色。
然后分块,对于散块暴力,大块维护,大块用 表存 即可。
设 为块长。
时间复杂度:
空间复杂度:
取 左右就能通过。
进一步有一个卡常是预处理只出现了一次的颜色,这个可以前缀和维护, 的大小就会变成原来的 。
15.隔膜
满分做法和倒着 的做法没有任何关系,不写。
考虑正向贪心,每个人应该有怎么样的决策。
每个数首先都大于等于 ,所以变成自己的那一面一定更好。
如果一个人只有至多一个不是自己的面,翻它。
否则陷入一个选择, 和 翻谁。
先说出结论,如果 是一个后缀 ,那么翻 ,否则翻 。
证明感性理解一下就是如果翻了 ,后面会换来一个后缀 ,和 比较大小,多手玩一下也可以发现。
然后就可以用 来维护后缀 ,以及选择 的位置,这样一来发现所有 的正反面都是很有规律的,只有被选择来选 的后缀 位置,是和初始不同的。
时间复杂度:
16.Dungeon Crawler
17.Where Am I?
18.CowMooing
19.Color a Tree
20.Wild West
21.Peaks
22.Sorting a Matrix
23.Random Walk to Millionaire
24.Constrained Sums
25.Chocolate
简单题,直接按照 排序就是对的。
时间复杂度: