Loading

CF1923 VP 记录

CF1923 VP 记录

AB 跳了。

C. Find B

赛时切了。

题意

如果存在一个整数数组 \(b\) 满足以下条件,则认为一个整数数组 \(a\) 是好的:

  • \(|b|=|a|\)
  • \(a_i\neq b_i\)
  • \(\sum b=\sum a\)
  • \(b_i>0\)
    给定一个数组 \(c\)\(q\) 次询问,要求判断 \(c[l,r]\) 是不是好的数组。
    可以做到 \(\Theta(n+q)\) 的复杂度。

做法

考虑一种构造方案,给所有数都减一,然后给最后一个数加上减去的总和。

这样显然是可行的。

但是可能有 \(1\),就不能减了。

所以 \(1\) 就得变成 \(2\)

这样数字的总和可能就不够用了。

所以我们判断这种情况就好了。

所以我们的构造方案就是:把所有大于 \(1\) 的数减一,然后把所有 \(1\) 都至少加一。判断这样构造数字的总和够不够用即可,也就是区间中 \(1\) 的个数是否小于等于区间的和减去区间长度。

D. Slimes

赛时不会,跳了。

题意

\(n\) 个史莱姆一字排开。这些史莱姆按照从左至右的顺序编号为 \(1\)\(n\),其中第 \(i\) 个史莱姆的大小为 \(a_i\)

每隔一秒会发生以下情况:恰好有一个 史莱姆会吃掉它的一个邻居,并且将它的大小增加被吃掉的邻居的大小。一个史莱姆只有在其大小严格大于邻居时才能吃掉这个邻居。如果没有史莱姆的大小严格大于其任意一个邻居,则该过程结束。

例如,假设 \(n = 5\)\(a = [2, 2, 3, 1, 4]\)。过程可能如下进行:

  • 首先,第 \(3\) 个史莱姆吃掉第 \(2\) 个史莱姆。第 \(3\) 个史莱姆的大小变为 \(5\),第 \(2\) 个史莱姆被吃掉。

  • 接着,第 \(3\) 个史莱姆吃掉第 \(1\) 个史莱姆(由于第 \(2\) 个史莱姆已被吃掉,它们相邻)。第 \(3\) 个史莱姆的大小变为 \(7\),第 \(1\) 个史莱姆被吃掉。

  • 然后,第 \(5\) 个史莱姆吃掉第 \(4\) 个史莱姆。第 \(5\) 个史莱姆的大小变为 \(5\),第 \(4\) 个史莱姆被吃掉。

  • 最后,第 \(3\) 个史莱姆吃掉第 \(5\) 个史莱姆(因为第 \(4\) 个史莱姆已经被吃掉,它们相邻)。第 \(3\) 个史莱姆的大小变为 \(12\),第 \(5\) 个史莱姆被吃掉。

对于每个史莱姆,计算在所有可能的过程演变中,该史莱姆被另一个史莱姆吃掉所需的最少秒数,如果不可能被吃掉,则报告“不可能”。

做法

我们分别考虑每一个史莱姆 \(i\)。它一定是被某一个与它相邻的史莱姆区间合并起来吃掉了。

考虑这个区间的性质:

  • 这个区间的和大于 \(a_i\)
  • 这个区间中的元素不是两两不同

这个东西是充分的,因为可以用区间最大值把区间中史莱姆全吃掉然后吃掉 \(i\)

题意就是要求一个最小的这样的区间。显然区间长度关于是否可行有单调性,二分一下就行了。

判断和很好维护,直接维护一个前缀和即可。判断值是否全部相同,我们考虑数组 \(b_i=[a_i=a_{i-1}]\) 的前缀和即可。

E. Count Paths

题意

给你一棵树,点有颜色,问有多少条路径满足:

  • 起止节点颜色相同。
  • 路径上没有与起止节点颜色相同的点。

做法

直接点分治即可。

我赛时想的是启发式遍历子树,\(O(n\log^2 n)\),应该也能过。

就是先用线段树合并维护出子树中有贡献的颜色的出现次数,然后启发式地遍历大小较小的子树即可。可以理解为重链剖分然后遍历轻子树,因为轻子树大小总和是 \(O(n\log n)\) 的,单次查询是 \(\Theta(\log n)\) 的,所以是 \(O(n\log^2 n)\) 的。

F. Shrink-Reverse

赛时没切。

题意

给你一个 01 串,你可以进行以下两种操作:

  1. 交换两个位置(不用相邻)。
  2. 去掉这个串的所有前导零,然后翻转整个串。

你要进行 \(k\) 次操作,问这个串转成二进制后最小是多少。

做法

性质1:不会进行超过两次 \(2\) 操作。

这个性质显然。

性质2:不会进行超过 \(1\) 次翻转操作。

考虑如果翻转一次之后 \(1\) 都连在一起了,那就不用动了。否则我可以用这一次操作把最高位挪到后面,这样是比翻转一次优的,因为最高位都更低了。

然后我们分类讨论这两种情况。

如果不翻转,我们直接贪心把最高位往最后放即可。

如果翻转,我们考虑我们不会做。因为翻转前后都会进行交换操作。

考虑我们最后形成的串是什么。

实际上就是把串翻转之后,找到一段区间,这个区间满足以下性质:

  • 这个区间的长度足够容纳所有的 \(1\)
  • 这个区间外的 \(1\) 个数小于等于 \(k-1\)
  • 这个区间转换成二进制后最小。

我们先二分一个长度,check 这个长度的区间有没有满足前两个条件的区间。

有了长度之后,我们记录一下哪些区间是合法的,然后用后缀数组找到最小的即可。

感想

这场感觉打得比较烂。

考得也不是比较偏门,主要是要多动脑子。

posted @ 2024-02-25 11:29  洛谷Augury  阅读(30)  评论(0编辑  收藏  举报