Nebius Round 2 (Codeforces Round 1088, Div. 1 + Div. 2) 题解
总结
一场坑害许多老师傅的比赛 + 注意力大赛,高僧预测出题组的帖子会迎来许多倒三角。
过题情况
| A | B | C1 | C2 | D | E | F | G | H | |
|---|---|---|---|---|---|---|---|---|---|
| 过题 | \(\color{green}3(+)\) | \(\color{green}23(+1)\) | \(\color{green}36(+)\) | \(\color{red}(-7)\) | \(\color{green}117(+)\) | ||||
| 补题 |
A
题意
给一个排列 \(p\),每次可以选择一个长度为 \(3\) 的子段删最大或者删最小,对排列中每个数求:如果在保留该数的前提下序列能删到最少,会剩几个。
题解
纯诈骗。除了 \(n=1\) 输出一个 \(1\) 以外,一律输出 \(n\) 个 \(2\)。可以证明对于所有数,每次都选含自己的序列,然后把不是自己的数删掉,因为这个数不论是最小/中间/最大,都能保证有不删掉自己的操作办法,因此最后一定会删到无法操作,此时除 \(n=1\) 以外恰好剩 \(2\) 个数。
B
题意
对序列 \(a\),定义 \(f(a)\) 是把 \(a\) 拆分成若干个总和相等的段的方案数(包括不拆)。现在给你 \(x\) 个 \(1\) 和 \(y\) 个 \(-1\),你需要构造一个序列 \(a\) 使得 \(f(a)\) 最小,并且输出方案。
题解
最小的构造方案是 \(x\) 个 \(1\) 和 \(y\) 个 \(-1\) 依次排在一起,此时 \(f(a)=d(|x-y|)\),其中 \(d(n)\) 表示 \(n\) 的不同正因子的个数。特别地,定义 \(d(0)=1\)。
证明:
为了方便,令 \(k=x-y\)。
易得每段序列的和必须是 \(|k|\) 的因子。序列只有 \(\pm 1\),那么数组前缀和一定是连续变化的,那么数组的前缀和一定会出现 \(|k|\) 的所有因子(如果 \(k<0\) 那就是对应的相反数,如果 \(k=0\) 那么只能保证一定会出现 \(0\))。
不妨设 \(k>0\),假设我们现在要求每段和为 \(g\),为了让方案数最小,我们直接把 \(-1\) 全部堆在右边,那么由于 \(g>0\),\(-1\) 必须选在最后一段(否则最后一段的和一定为负,不满足目标),把 \(-1\) 全部选完之后最后一段的选法就确定了,剩下的就是把一堆 \(1\) 分成若干个和为 \(g\) 的段,方案也是确定的。这样就保证对于每一个 \(g\),都恰好只有一种方案,因此最终方案数为 \(d(|k|)\)。类似地,\(k<0\) 就是确定第一段的拆法,\(k=0\) 就是直接确定了整个序列作为一段。
C
题意
给定长度为 \(n\) 的序列 \(a,b\),以及一个常数 \(k\),其中 \(b\) 某些项缺失,要求所有 \(b\) 的长为 \(k\) 的子段都必须是 \(a\) 对应位置子段重排的结果。
- 第一问:保证 \(a\) 是排列。
- 第二问:无其他限制。
第一问题解
我们假设有个滑动窗口从 \([1,k]\) 滑到 \([n-k+1,n]\)。始终在滑动窗口内的数可以任意重排,而进入滑动窗口的数和退出滑动窗口的数不一样,如果要保证 \(b\) 还是 \(a\) 的重排的话,\(b\) 进去的数必须等于 \(a\) 进去的数,出来的数类似,因此 \(a\) 和 \(b\) 对应位置的数必须相等。
第二问题解
施工中
D
题意
给定 \(a\) 的长度为 \(1 \sim n\) 的所有子序列求按位与后加起来的结果(对 \(10^9+7\) 取模,这个结果序列为 \(b_1,b_2,\cdots,b_n\)),构造长度为 \(n\) 的序列 \(a\),要求每个数必须在 \(0 \sim w-1(w=2^{29})\)之间,保证有解。
题解
拆位做。
如果只考虑 \(2^i\) 的位,首先需要注意到 \(a\) 的哪个数取 \(1\) 或者 \(0\) 不重要,重要的是有多少个取 \(1\)。那么如果出现 \(k\) 个 \(1\),这一位在 \(b_k\) 的贡献就是 \(2^i\),类似可以注意到在 \(r<k\) 的时候对 \(b_r\) 的贡献为 \(C_{k}^{r}2^i\),\(r>k\) 的时候贡献为 \(0\)。
对于一个长度为 \(r\) 的子序列,如果选到的 \(r\) 都是 \(1\) 就会产生 \(2^i\) 的贡献,否则不产生贡献,如果 \(2^i\) 上有 \(k\) 个 \(1\),那么可以知道能产生贡献的子序列个数一定是 \(C_{k}^{r}\)。
由于 \(2^i\) 最大对 \(b_k\) 产生贡献的 \(k\) 和 \(2^i\) 出现的总个数恰好相等,也就是说在只考虑 \(2^i\) 这一位的情况下从大到小遍历 \(k\),第一次出现的非零的 \(b_k\) 的位置就是 \(2^i\) 出现的个数,而且此时 \(b_k\) 恰好等于 \(2^i\)。
因此,回到原问题(也就是考虑所有位),我们从大到小遍历 \(k\),把所有出现个数 \(>k\) 的位对 \(b_k\) 的所有贡献都减掉之后,剩下的 \(b_k\) 就直接对应了哪些位刚好有 \(k\) 个 \(1\),然后直接构造即可。
时间复杂度 \(O(n\log w)\)。
浙公网安备 33010602011771号