Codeforces Round 969 (Div. 1) 记录

Codeforces Round 969 (Div. 1) 记录

场切了 ABC,2:23 过的 C pretest,DEF 都没开到(

A

简单博弈题。\(\texttt{Clist *} \color{blue}{1743}\)

对于除了首尾以外的 \(0/1\) 连续段,都会提供恰好一个 \(01\) 和恰好一个 \(10\)

如果开头是 \(1\) 则不会提供 \(01\) ,结尾是 \(1\) 则不会提供 \(10\),这两个又可以抵消掉,\(0\) 同理。

因此得到,一个叶子会提供 \(1\) 的得分,当且仅当这个叶子的权值和根的权值不同。

那可以做简单分讨。设叶子节点上的问号数量是 \(x\),非叶子上的问号数量是 \(y\)

如果根节点上不是问号,那么 Alice 能得到的答案增量是 \(\lfloor(x + 1) / 2\rfloor\)

如果跟节点上的值是问号,当叶子节点上的 \(1\) 的个数和 \(0\) 的个数不相等时,Alice 可以先手令根节点的权值是叶子节点上 \(1\) 的数量和 \(0\) 的数量较少的那个数,并获得 \(\lfloor x / 2\rfloor\) 的增量。

否则,谁拿到根谁吃亏,可以通过判断 \(y\) 的奇偶性简单判断 Alice 取 \(\lfloor (x + 1) / 2\rfloor\) 还是 \(\lfloor x / 2\rfloor\)

B

\(\texttt{Clist *} \color{purple}{2033}\)

答案单调下降,因此考虑离线后时光倒流计算增量。

首先考虑在什么情况下取到一条路径上的最大答案。

时光倒流后,相当于一开始给定一棵树,我们称每次操作是选定一条边制约解除

那么设当前所有被制约解除的边的边权和为 \(v\),那么对于一条路径经过的边,有一部分被制约解除了,一部分没有,设没有被制约解除的边的边权和为 \(u\)。假设这条路径上存在一条边被制约解除,那么这条路径的边权就是 \(u + v\),否则权值为 \(u\)

考虑题目中路径的性质。树是按 dfs 序编号的,那么每条边会被两条 \(i \rightarrow (i \bmod n + 1)\) 的路径经过。对于点 \(i\),设 \(i\) 的子树内的编号范围为 \([i, r_i]\),那么每次解除 \(i\)\(i\) 父亲的这条边,影响到的只有 \((i - 1) \rightarrow i\) 的路径和 \(r_i \rightarrow (r_i \bmod n + 1)\) 的路径。

那么问题就变得很简单了。首先算出所有边权都确定时的答案,并记一个 \(cnt\) 描述当前存在被制约解除的边的路径的条数和一个 bool 数组描述每一条路径中是否存在被制约解除的边。

对于每次操作,设当前的边的权值为 \(val\)。首先当前的边先消除影响,将答案减去 \(2val\),然后把 \(val\) 加到 \(v\) 中。

因为每次只会修改两条路径,所以可以直接修改 bool 数组并维护 \(cnt\),然后再让答案增加 \(cnt \cdot v\) 即可。

C

\(\texttt{Clist *} \color{orange}{2307}\)

喜欢我猜结论题吗?

首先每次拿到一个数组,显然将它一直操作直至无法操作为止后如果连续就不合法。

考虑无法操作的集合是什么样子的。假设集合内有两个数的差为偶数那么一定操作。而无法操作即无论选择哪两个数操作,其能产生出的数都已经在集合中了。

然后手玩下发现,不能操作当且仅当这段数组从小到大排序后,差分数组的 \(\gcd\) 不是 \(2\) 的整数次幂或 \(0\)

胡个证明。首先如果排序后两个相邻数作差后是偶数,那么显然将它一直操作下去。最后可以得到一个任意相邻数的差都为奇数的数组。

那么假设场上出现的间隔的种类数超过 \(1\) 种,那么一定有一组 \((i, i + 1, i + 2)\) 满足 \((a_{i + 1} - a_i) \not = (a_{i + 2} - a_{i + 1})\)。此时 \((i, i + 2)\) 必然可操作,并且操作后出现的数一定没有出现过。那么一直执行上述操作,最后就能得到一个所有数相等的数组,并且这个相等的值显然是所有差分的 \(\gcd\) 不断除以 \(2\) 的结果。而如果最后所有差都是 \(1\) 那就达到目的了,推回去就是 \(\gcd\)\(2\) 的整数次幂就是合法的。

问题变成了,问有多少个子段排序后的差分的 \(\gcd\)\(0\)\(2\) 的整数次幂。

然后胡个结论,排序后的差分的 \(\gcd\) 等于不排序时差分的绝对值的 \(\gcd\)

证明它。根据 \(\gcd\) 的性质有 \(\gcd(a, b) = \gcd (a + b, b)\),所以我们可以把差分给前缀和回去 \(\gcd\) 不变,然后发现前缀和后的数组时原数组每个数都减去最小值的结果。然后我们任意调换原数组的顺序后,原数组每个数都减去最小值的 \(\gcd\) 是不变的。而排序后的 \(\gcd\) 恒为正,所以很自然的每个数差分后取绝对值的 \(\gcd\) 是不变的。

那就直接把差分处理出来得到一个长度为 \(n - 1\) 的数组,问题变成了有多少个子段的 \(\gcd\)\(0\)\(2\) 的整数次幂。问题变成了 ARC023D] GCD区間,简单 st 表后二分并开 map 存起来即可,当然这题因为询问数量极小肯定有更快的做法(sol:st 表后双指针或直接不带删双指针)。但是赛时一看转化成这题就懒得继续思考了。

D

赛后补题,启动!

\(\texttt{Clist *} \color{red}{2673}\)

大家好啊今天给大家带来点根分。

考虑最优顺序。显然先放 \(a_n\),然后放 \(a_1\), 然后放 \(a_{n - 1}\) 这样,大值小值交替着放。

证明考虑各种邻项交换证最优性。

考虑当前数组合法的条件。设当前数组中满足值在 \([i, j]\) 的数字的个数为 \(cnt(i, j)\)

考虑合法条件。对于 \(\le i\) 的数,它需要应付所有大于 \(\lfloor\frac {k}{i + 1}\rfloor\) 的数吧,因为 \(i + 1\) 没法应付这种数,所以至少 $\le i $ 的数应该足够。

然后还有种情况。如果长度为奇数,那么中间那一项是不用考虑的。

那么合法需要满足的就是 \(\forall i \in [1, \sqrt k], \min(cnt(1, i) , \lfloor \frac n2 \rfloor )\ge \min ( cnt(\lfloor\frac k{i + 1}\rfloor + 1, k), \lfloor \frac n2 \rfloor)\)

而考虑下修改是什么。显然最大值改成 \(1\)。那么会使得 \(i \le \sqrt k\)\(cnt(1, i)\) 的值均加上 \(1\) 并让 \(i > \sqrt k\)\(cnt(i, k)\) 减小 \(1\) 吧。

那找一下差多少就行了吧。

然后出题人很良心的卡了二维前缀和的空间,考虑卡空间。

操作离线下来,每次对于每个 \(i\) 求出该求的数据就行了吧。

实现上,枚举 \(i \le \sqrt k\),然后把 \(i\)\(\lfloor \frac {k}{i + 1} \rfloor\) 对所有询问的贡献搞出来就行了。

posted @ 2024-09-01 17:58  AzusidNya  阅读(81)  评论(0)    收藏  举报