Codeforces Round 945 (Div. 2) 记录
__vector__ · · 个人记录
废话区
真希望这场没读错 D 题,或者先去做 E。
选任意一个选项,用大号打都能紫,然而我用的小号,而且 D 读错题了,E 赛时直接没看,再加上 C 对着题目保证不存在的
A
首先判定总和为奇数的情况无解。
然后每次贪心删最大的两个,由于数据小,懒得推式子的话,multiset 模拟就可以。
B
有两种做法,我赛时写的是
我赛后测试,看着差了一个 log,但后者速度是前者两倍。
- 做法 1:
如果写一个暴力程序模拟样例,那么会发现存在单调性,即存在一个分界点,
k 比这个小一定不符合要求,比这个大一定符合要求。
关于证明,假设现在有一个k_1 满足k=k_1 满足条件,那么事实上,经过一定思考可以比较容易得出这个结论(下一个做法用到):\forall i \in [1,n-k_1+1] ,满足a_i | a_{i+1} | a_{i+2} | \cdots | a_{i+k_1-1} = a_1 | a_2 | a_3 | \cdots | a_n 。
现在,每个位置开头的连续k_1 个的数的 or 值还要再 or 下一个数,而每个位置新 or 的数显然已经包含在自身了,所以不会改变自身原本的值。
现在就可以二分求解本问题了。 赛时记录 - 做法 2:
根据做法 1 的结论,对于一个合法的k ,\forall i \in [1,n-k+1] ,满足a_i | a_{i+1} | a_{i+2} | \cdots | a_{i+k-1} = a_1 | a_2 | a_3 | \cdots | a_n 。
可以提前计算出整体 or 值,然后对于每个位置,计算这个位置向后延申多少个位置,or 值等于整体 or 值,最后对于所有位置,这个值取 max 就是答案。
赛后记录C
我赛时的分讨结论:不论
n 奇偶,最优答案一定是2,4,6,8,\cdots 位置为局部 max,或3,5,7,9,\cdots 位置为局部 max。
先假设已经选好了第一种还是第二种,最劣情况是选中的值是
由于值为
考虑第一种,如果第
反之,如果存在呢?
那就跳过它就好了,选第二种构造,因为只要选中的数不存在
赛时记录
D
赛时看成了所有加起来等于
看到这题,我第一个想到的是根据最大值。
事实上可以通过
然后,注意,划分成
那么注意,整体最大值肯定也是它所属的段的最大值。
所以,只需要枚举整体最大值所在段的长度,并判定是否合法就可以。
比较容易得出,整体最大值所在段的长度一定不超过
然后,每次判定需要
赛后记录
E
这题感觉也就 1800 难度,为啥放 E 啊赛时没机会看。
考虑
其中
草稿纸上模拟一下,可以发现事实上
然后就有了本题解法。
将能交换的两个数放到同一个连通块,最后同一个连通块内的所有数都可以互相交换。
草稿纸上模拟一下
然后发现了一个惊喜:
那么对于
略微思考可得
所以说,对于
再来想想
考虑先找出任意一对原序列中需要互相交换位置的数字
如果存在
接下来,就是对于所有需要互相交换的数字,判断和是否为
如果全部满足,那么存在一组
赛后记录
F
暂时不会。