ARC135 赛后总结
比赛链接:https://atcoder.jp/contests/arc135/tasks/arc135_a
A. Floor, Ceil - Decomposition
题目链接:https://atcoder.jp/contests/arc135/tasks/arc135_a
题目大意:每次你可以选择一个数字,分为 $\left\lfloor \frac{x}{2} \right\rfloor, \left\lceil \frac{x}{2} \right\rceil$ ,一开始只有一个数字 $X$ ,问你最终可能的乘积最大值是多少。
做法
很弱智,显然 $\ge 4$ 直接分就行了。
最后只会剩下 $2,3$ 。
但是我的写法比较 SB 。
我写了个堆 + map,每次把最大数字弹出并且记录个数。
1 |
|
有没有更加好写的写法?
有,记忆化搜索。
也是我认为最好写的写法。
1 |
|
还有一种写法是直接记录 $\left\lfloor \frac{x}{2^k} \right\rfloor, \left\lceil \frac{x}{2^k} \right\rceil$ 以及其个数,直到组合为 $\{2,3\},\{3,4\}$ 时结束。
但我个人感觉这种写法就算比第一种写法好写,也容易写错,所以赛时没有使用。
具体代码没写。
B. Sum of Three Terms
题目链接:https://atcoder.jp/contests/arc135/tasks/arc135_b
题目大意:给你一个数组 $S$ ,要求找到一个长度为 $n+2$ 的数组 $A$ 满足:
- 非负。
- $S[i]=A[i]+A[i+1]+A[i+2]$
做法
注意到 $S[i+1]-S[i]=A[i+3]-A[i]$ 。
所以条件可以等价成:$A[1]+A[2]+A[3]=S[1]$ ,以及 $A[i]-A[i-3]=k$ ,以及要求非负。
那么直接求出在非负条件下 $A[1],A[2],A[3]$ 的下界,然后直接随便定个初值就行了。
1 |
|
跟官方做法本质相同,在此不再赘述。
C. XOR to All
题目链接:https://atcoder.jp/contests/arc135/tasks/arc135_c
题目大意:给你一个序列,每次可以选择其中一个数字,然后让序列中所有数字异或这个数字,问最后得到的和的最大值是多少,可以操作无数次。
做法
注意到一个事情,最终答案一定是所有序列异或上某个数字,而且只要操作过,就一定有数字为 $0$ ,综上,我们直到无论操作多少次,都等价于让序列异或上原来序列中的一个数字,也就是操作多次=操作一次。
所以直接枚举统计答案就行了。
时间复杂度:$O(n\log{V})$ 。
1 |
|
D. Add to Square
题目链接:https://atcoder.jp/contests/arc135/tasks/arc135_d
题目大意:给一个表格,然后可以执行一个操作:选择一个 2*2 的子矩阵,然后让其加上同一个值(可以为负数),可以执行无数次,问最小的可能的绝对值和是多少。
做法
一个很典的想法是,先给这个操作找到不变量。
可以发现,如果将表格奇偶染色,然后将奇数格变成负的,然后将操作做对应的变换,那么整个矩阵的和就是不变量,而且不影响最终答案。(显然取负值并不改变绝对值的和)
所以变成这样的问题:选择一个 2*2 的矩阵,使得 $(1,1),(2,2)$ 加上 $x$ ,$(1,2),(2,1)$ 减去 $x$ 。
又可以发现,这里我们相当于有 $(n-1)(m-1)$ 个方程,且不线性相关,所以我们能把左上角消成 $0$ ,只保留最右边和最下边。
但是剩下的数字是多少,这个时候就可以发现,其实每行和每列的和也是不变量,这决定了在把左上角矩阵消成 $0$ 后的矩阵长啥样。
接着就可以发现:两个矩阵能互相到达当且仅当每行和每列的和是一样的。
然后就可以做了,不难发现答案的上界是:行的和的绝对值和,和列的和的绝对值和的最大值。
构造方案就是一个匹配的活。
时间复杂度:$O(nm+n^2+m^2)$ 。
做毕。
1 |
|
E. Sequence of Multiples
题目链接:https://atcoder.jp/contests/arc135/tasks/arc135_e
题目大意:给定 $N,X$ ,要求构造一个和最小的长度为 $N$ 的序列 $A$ 满足:
- 严格递增。
- $A_1=X$
- $A_{i}$ 被 $i$ 整除。
做法
注意到一个事情:$A_i=i*B_i$ 。
那么 $A_{i}\equiv -B_i \mod{i+1}$ 。
我们显然关心 $A_{i+1}-A_{i}$ ,而这个显然等于:$B_{i}\mod i+1$ (注,由于严格递增,在整除的时候为 $i+1$)
当 $B_{i}<i+1$ 时,就为 $B_{i}$ ,而且不难发现以后也为 $B_{i}$ 。
即 $B_{i}$ 是非严格单调递减的,而且当 $B_{i}\le i+1$ 后,$B_{i}$ 保持恒定。
具体来说:$B_{i+1}=B_{i}-\left\lfloor\frac{B_{i}-1}{i+1}\right\rfloor$
但是我们可以发现,这个保持恒定的量级可以到 $10^9$ 。
$\ge$ 是显然的,$\le$ 也不难:
往极坏的角度想:在 $i$ 的时候就 $+i$ 。
那么在 $2e9$ 的时候就是:$1e18+\frac{(2e9+1)*2e9}{2}<2e9^2$ 。
所以在 $\le 2e9$ 的时候进入恒定状态。
但我们显然不可能枚举这个量级,怎么办呢?
在苦思冥想下,我突然意识到,复杂度有没有可能是:$O(n^{\frac{1}{3}})$ 的。
因为可以发现在 $1e6$ 量级后,$\frac{B_i-1}{i}$ 的量级也是 $1e6$ 的。(与上面的证明方法类似)
而且 $\left\lfloor\frac{B_{i}-1}{i+1}\right\rfloor$ 是单调递减的,这意味着 $B_{i+1}-B_{i}$ 在 $1e6$ 之后只会有 $1e6$ 种可能的取值。(以上指的都是量级)
所以直接二分出每个可能取值的分界点,就可以在 $O(n^{\frac{1}{3}}\log{n})$ 的复杂度内解决了。
后面发现二分的判别式是一个线性函数,因此可以 $O(1)$ 找到分界点。
而且类似整除分块的,在 $1e6$ 之前的部分同样也可以用这个函数处理,因为也只有 $1e6$ 种取值,不过限制取值数量的条件不是值域,而是定义域,这时求出来的分界点很集中,基本就是自己。
然后就做完了。
时间复杂度:$O(Tn^{\frac{1}{3}})$ 。
1 |
|
但因为没在赛时推出正确的式子,导致无法在赛时 AC 。
不过是 VP ,问题也不是那么大。
和官方做法基本一致,在此不再赘述官方做法。
别的做法
https://www.luogu.com.cn/article/thzagqey
有一种做法,是打表,发现在 $\sqrt{x}$ 后 $A$ 变成了等差数列。
差分一下,发现序列由 $n^{\frac{1}{3}}$ 段等差数列构成,并且总是在即将 $\le 0$ 后转换到下一个等差数列。
更准确的来讲,是说可以把序列分成若干段等差数列,每段都在即将 $\le 0$ 时结束,等差数列的长度可以为 $1$ 。(后面会讲为什么)
直接计算就行了。
时间复杂度:$O(Tn^{\frac{1}{3}})$ 。
问题来了,为什么?
首先等差数列不难理解,在我的做法中,$B_{i-1}-\left\lfloor\frac{B_{i-1}-1}{i}\right\rfloori=B_{i-1}-(B_{i-1}-B_{i})i=B_{i}i-B_{i-1}(i-1)=A_{i}-A_{i-1}$ 就是 $A$ 的差分,二分中的每一段实际就是 $B$ 差分相等的部分,即我们认为:$B_{i+k}=B_{i}-kd$ 。
则有:
即 $A$ 的一阶差分是个等差数列。
但为什么总是在即将 $\le 0$ 后转换到下一个等差数列呢?
而分界点的条件可以表示为:
最大的 $k$ 满足:$\left\lfloor\frac{B_{i+(k-1)}-1}{i+k}\right\rfloor \ge d,\left\lfloor\frac{B_{i+k}-1}{i+k+1}\right\rfloor < d$ ,这里 $\ge$ 可以写成 $=$ 。
也就是:
这就证明了这件事情。
但需要注意的是:可以发现,一段长度为 $len+1$ 的 $B$ 的等差数列,对应 $A$ 的差分序列的一段长度为 $len$ 的等差数列,因此会有很多长度为 $1$ 的等差数列。(虽然可以认为相邻两个数字是等差数列,但是这种等差数列并不满足上面的将要 $\le 0$ 就切换到另外一个等差数列的性质)
为此,在实现中的一个简单的解决方法是直接算出后 $10$ 项,如果满足等差数列就直接算,赌他不会这么巧恰好由 $10$ 个长度为 $1$ 的等差数列构成。
但是我们还是希望知道什么时候 $len$ 会稳定的 $\ge 2$ 呢?
我们先设 $C_{i}=B_{i}-1$ ,那么 $C_{i+1}=C_{i}-\left\lfloor\frac{C_{i}}{i+1}\right\rfloor$ 。
那么问题可以抽象成这样:
现在有 $i+1$ 个柱子,均匀放,每次将最少东西的柱子的东西删除,再添加一个柱子均匀放,问经过几轮后能够出现稳定两轮删除的东西数相同?
设 $D_{i}=\left\lfloor\frac{C_{i}}{i+1}\right\rfloor$ ,这里给一个必要条件,当 $D_{i-1} ≠ D_{i}$ 且 $6D_{i}+1\le i$ 时,在此之后 $len\ge 1$ 。
证明就是假定一个 $i*D_{i-1}$ 的长方形(这样对后面的亏损是最大化的),然后开做这个补的过程,发现可以做至少两次,同时可以证明此时 $D_{i-1}=D_{i}+1$ ,所以只能用最上面那一行来补就证明完了。
我们想要估计出 $i$ 的量级:
这条式子在 $\ge 2*10^6$ 处总是满足,而且显然是 $O(n^{\frac{1}{3}})$ 的。
问题就在于什么时候:$D_{i}≠D_{i+1}$ 。
设 $a_{i}=A_{i}-A_{i-1}$ 。
如果 $a_{i+1}>a_{i}$ 或者 $a_{i}-a_{i-1}≠a_{i+1}-a_{i}$ ,那么显然 $D_{i}≠D_{i-1}$ 。
否则:$a_{i-1}\ge a_{i}\ge a_{i+1},a_{i-1}-a_{i}=a_{i}-a_{i+1}$ ,那么有如果 $D_{i-1}≠D_{i}$ ,那么从 $i$ 开始就有长度为 $2$ 的等差数列,公差为 $a_{i}-a_{i+1}$,否则 $D_{i-1}=D_{i}$ ,这个时候 $i$ 依旧是公差为 $a_{i}-a_{i+1}$ 的等差数列的一部分,直接计算就行了。
也就是说,在 $2e6$ 后我们可以在 $O(1)$ 的时间进入求等差数列的过程,这个过程就是:求出公差,一直算到 $\le 0$ 为止,然后接着求下一段直到 $\ge n$ 。(因为 $A$ 为等差数列的阶段等价于 $a$ 为恒为 $0$ 的等差数列的阶段,只不过这个等差数列不会结束而已)
这样这个做法就比较好实现了。
综上,时间复杂度:$O(Tn^{\frac{1}{3}})$ 。但问题是如果我都会证明这个了为什么不直接用上面这个做法
其实说的道理,既然一开始就选择了打表,不妨在实现时就使用多算几项估计一下等差数列,也不会有多难写,还充分发扬了打表省时间的优势,如果尝试证明的话就会浪费不少时间了,不过赛后确实可以花时间证证。