题解 Codeforces Round 887 (Div 2) / CF1853A~F

下大分!悲!Div 1 只过了 1A!!!

但还是补完整场 Div 2 吧。

A. Desorting

https://codeforces.com/problemset/problem/1853/A

problem

用操作:\([1,i]++,[i+1,n]--\),使得数组不单调不降,求最小操作次数。\(n\leq 10^5\)

solution

操作等同于在差分数组上选出 \(i\),做 \(c_1:=c_1+1,c_i:=c_i-2\);又因为除了无用的 \(c_1\) 外,只要 \(c_{[2,n]}\) 中有一个负数,那么对应的原数组就会出现 \(a_{i-1}>a_i\) 的题设。那么先做差分,找到 \(c_{[2,n]}\) 中的最小值,如果已经无序就是 \(0\),否则是 \(x/2+1\)

B. Fibonaccharsis

https://codeforces.com/problemset/problem/1853/B

problem

Fibonacci-like 的序列,满足单调不降,全部数非负,\(F_i=F_{i-1}+F_{i-2}(i>2)\)。问有多少个 Fibonacci-like 的序列满足 \(F_n=k\)\(n\leq 10^9,\sum k\leq 10^5\)

solution

\(F_1=b,F_2=a\)\(f_1=f_2=1\)\(F,f\) 都为 Fibonacci-like(后者就是 Fibonacci)。尝试归纳证明一个重要结论:\(F_i=af_{i-1}+bf_{i-2}\)

  • 归纳的基石是显然的。
  • \(F_i=F_{i-1}+F_{i-2}=af_{i-2}+bf_{i-3}+af_{i-3}+bf_{i-4}=a(f_{i-2}+f_{i-3})+b(f_{i-3}+f_{i-4})=af_{i-1}+bf_{i-2}\)。证毕。

那么原题就是求 \(F_n=af_{n-1}+bf_{n-2}=k\) 的方案数。其实这个 \(f\) 增长非常之快以至于这个东西可以直接暴力。大概 \(30\)\(f\) 就可顶爆 \(10^5\)。于是枚举 \(b\) 即可。注意单调不降。

C. Ntarsis' Set

https://codeforces.com/problemset/problem/1852/A

problem

集合 \(S=N^{+}\) 初始时。重复 \(k\) 次,每次都同时删除 \(a_1,a_2,\cdots,a_n\) 小的元素。求操作后 \(S\) 中最小数。\(n,k\leq 10^5\)

solution

可以考虑原集合的前 \(m\) 个数,每一天,这 \(m\) 个数中的某一些会被删除。因为我们规定这 \(m\) 个数是前 \(m\) 个数,所以删除就是删这 \(m\) 个数的 \(a_1,a_2,\cdots,a_n\) -th。可以二分找出多少个数被删除,也就是记 \(x=\sum_{i}[a_i\leq m]\),然后 \(m:=m-x\),继续下一天。如果最终还剩下数字,说明 \(m\geq ans\);如果删空了,\(m<ans\)。那么二分答案即可。\(O(n\log^2n)\)

另一种做法是关心最小值位置,好像是在 \(a_1-1,a_2-2,\cdots,a_n-n\) 这些地方插入零之类的,然后可以线性。

D. Imbalanced Arrays

https://codeforces.com/problemset/problem/1852/B

problem

构造非零整数数组 \(b\) 使得:

  • \(-n\leq b_i\leq n\)
  • 任意两个 \(b_i\) 不为相反数;
  • 恰好有 \(a_i\)\(j\) 使得 \(b_i+b_j>0\),包括自己。

构造或者无解。\(n\leq 10^5\)

solution

首先变形 \(b_i+b_j>0\Rightarrow b_j>-b_i\)。当 \(b_i\) 越大,\(-b_i\) 越小,找到的 \(a_i\) 越大。对着 \(a_i\) 排序就能确定 \(b_i\) 的大小关系。

对于符号,如果记 \(a_i\) 排序后 \(a_i\) 最小值的下标为 \(p_1\),最大值为 \(p_n\)

  • 对于 \(a_{p_n}\),如果 \(a_{p_n}=n\),说明 \(b_{p_n}\) 的相反数小于其它所有数,不妨给它值 \(n\)
  • 对于 \(a_{p_1}\),如果 \(a_{p_1}=0\),说明 \(b_{p_1}\) 的相反数比其他值都大,因为它的值最小,所以它一定是 \(-n\) 了。
  • 按照这样的思路,我们双指针,按照 \(x:n\to 1\) 的顺序,维护 \(l,r\),每次确定一个 \(b_{p_l}\) 或者 \(b_{p_r}\) 的值为 \(\pm x\)
  • 我们坚信如果这样的算法无法得出解,则原问题无解。

E. Ina of the Mountain

https://codeforces.com/problemset/problem/1852/C

problem

给出长为 \(n\) 的数组 \(a\)。构造尽量少的区间减操作,使得操作完后,所有 \(a_i\equiv 0\pmod k\)\(n\leq 10^5,k\leq 10^9\)

solution

这个问题相当于 [NOIP2013 提高组] 积木大赛,但是输入的值是对 \(k\) 取模的,我们要最小化答案;在某些情况下,给某个点加 \(k\) 会影响答案(如样例二)。回忆积木大赛的结论,是所有正的差分值之和。考虑从左到右去加入数字使得差分总和最小。我们发现其实使得尽可能多的 \(c_i\) 为负是最优的,但是我们不能对数字减 \(k\),不能强行减到负数使得它的差分全为负。

考虑一种贪心:

  • 我从左往右加入 \(a_i\),先把 \(a_i\) 加上和 \(a_{i-1}\) 一样个数的 \(k\),使得它们持平。
  • 如果 \(a_{i-1}>a_i\) 我就不管。
  • 如果 \(a_{i-1}<a_i\),我们也许可以使得 \(a_{i-1}\) 额外多加一个 \(k\),但这样会影响更前面的答案,我们希望找到前面一个点,使得这一段全部加 \(k\),影响集中到那个点上。

对于最后一种情况,解决的方案是反悔贪心。维护一个决策集合,每个决策表示我可以花 \(x\) 的代价,使得 \(i-1\) 到前面的某一个点 \(j\) 全部加 \(k\),这个 \(x\) 的代价就是原来 \(a_j\) 因为 \(<a_{j-1}\) 不计算的差分,现在算上 \(a_j+k-a_{j-1}\)。重新设计贪心算法:

  • 如果 \(a_{i-1}>a_i\),答案不用加,决策集合里面放入 \(a_i+k-a_{i-1}\)
  • 如果 \(a_{i-1}<a_i\),将我直接将答案加 \(a_i-a_{i-1}\) 和取前面一个决策的两种方案作比较,选一个最小的加入答案。对于后者,还需要在决策集合里面放入 \(a_i+k-a_{i-1}\),表示我以后可能还要反悔,可能又不加这个 \(k\) 了,给 \(a_i\) 加回去打平成原来的样子。

那么这个反悔贪心是对的。决策集合需要插入,查询 \(\min\),删除 \(\min\),一个堆即可。

F. Miriany and Matchstick

https://codeforces.com/problemset/problem/1852/D

看了题解,好厉害。

怎么是 WIP

挂个同行题解先 https://www.cnblogs.com/oierpyt/p/17578479.html

problem

两行字符串 \(a,b\),由 A/B 组成,第一行已经给定了,请填第二行,使得填完之后相邻不同对(\([a_i\neq b_i]+[a_{i-1}\neq a_i]+[b_{i-1}\neq b_i]]\))数量恰好为给定的 \(k\)\(n\leq 10^5\)

solution 1

考虑从左往右一个一个字符填,考虑每一次的增量,不妨写个 DP 形式,\(f_{i,d}\) 表示 \(b_i=d\) 时的 \(k\) 的集合,其中 \(k\) 已经减掉 \(a\) 自己的贡献。

\(f_{i,d}=f_{i-1,d}\cup(f_{i-1,d\oplus 1}+1)+[a_i\neq d]\)

最终结论是,\(f_{i,0},f_{i,1}\) 满足:它们之间有交,最多有一个是一个区间中间扣掉一个数,也就是集合是 \(O(1)\) 个区间。可以数学归纳法证明,画几个图,大概就是:归纳基石显然,然后每次右移的过程,刚好接上之后,要么是并起来并没了,要么叠在一起,最终就这样了。算了不如看 官方题解

然后方案就是逆推,看一下这个 \(k\) 来自哪里,倒着确定即可。

Codes

posted @ 2023-07-24 22:51  caijianhong  阅读(202)  评论(2编辑  收藏  举报