临时存储文章

Codeforces Educational Round 153

T1,T2,T3

比较简单的题目。

T4

首先存在一个观点:一个位置至多只会被交换一次。因为交换两次的情况可以被某一种交换一次的方案替代。比如 101 101 101 进行 ( 1 , 2 ) , ( 1 , 3 ) (1,2),(1,3) (1,2),(1,3) 两次交换 得到序列 110 110 110,可以使用一次交换 ( 2 , 3 ) (2,3) (2,3) 达到相同的效果。

故我们知道:每个点的颜色最多只会反转一次。我们可以将异色位置对 ( i , j ) (i,j) (i,j) 颜色的交换看成两个分立的过程:将 i i i 的颜色反转,将 j j j 的颜色反转。

考虑最后需要满足的条件:

  • 反转的 0 / 1 0/1 0/1 个数相同。
  • 10 10 10 子序列的数量变化量 = 原串 1 的数量 × 原串 0 的数量 2 − 原串 01 子序列数量 \displaystyle =\frac{原串 1 的数量 \times 原串 0 的数量}{2}-原串 01 子序列数量 =2原串1的数量×原串0的数量原串01子序列数量

设计 DP 状态 F i , j , k F_{i,j,k} Fi,j,k 表示前 i i i 个位置, 0 0 0 反转个数 − - 1 1 1 反转个数为 j j j 01 01 01 子序列变化量为 k k k

转移时间复杂度为 O ( n 4 ) O(n^4) O(n4)

T5

考虑如下建图:每个间隙向左右建边;对于每种不同种类的空隙建立一个超级源点,并且向所有该种类的点建边。
那么对于每一种询问可能存在两种路径:

  • 不进行相同种类的跳转。
  • 进行过至少一次相同种类的跳转。

注意到空隙的种类数只有 26 ∗ 26 26*26 2626 种,枚举种类 T T T,从其超级源点 S T S_T ST 跑一次单元最短路。接下来检查所有询问经过 S T S_T ST 的情况:即使用种类 T T T 的跳转。

总时间复杂度为 O ( n 2 6 2 ) O(n26^2) O(n262)

T6

24oi 2023.8.23

做题记录

T1

T2

取模存在性质:
如果 p ≡ q (   m o d     ( A B ) ) p\equiv q(\bmod\ (AB)) pq(mod (AB)),那么 p ≡ q (   m o d     A ) p\equiv q(\bmod\ A) pq(mod A)

考虑题目里同余方程的形式:
x p i ≡ q i (   m o d   ∏   p ) x^{p_i}\equiv q_i(\bmod \prod\ p) xpiqi(mod p)
发现可以在模数上做手脚:
x p i ≡ q i (   m o d     p i ) x^{p_i}\equiv q_i(\bmod\ p_i) xpiqi(mod pi)
那么考虑费马小定理有:
x p i − 1 ≡ 1 (   m o d     p i ) x ≡ q i (   m o d     p i ) \begin{aligned} x^{p_i-1}&\equiv 1(\bmod\ p_i)\\ x&\equiv q_i(\bmod\ p_i) \end{aligned} xpi1x1(mod pi)qi(mod pi)

那么变成了普通的 CRT 形式。考虑和原问题的关系:
这个转换是向松的方向转化。而 CRT 可以求出   m o d     n \bmod\ n mod n 下的唯一解。故我们只需要判定这个解是否合法即可。可以暴力检查即可。

T3

构造出的最优解肯定形如这样:耗费若干代价在几个位置放上棋子,然后剩下的连续空段可以不消耗代价填上。

考虑什么样的连续空段是可以 0 0 0 消耗可以填满的。从长度为 1 1 1 的段反推,序列满足这样的递推式:
F i = { 1 ( i = 1 ) 2 F i − 1 + 1 ( i > 1 ) F_i= \begin{cases} &1 &(i=1)\\ &2F_{i-1}+1&(i>1) \end{cases} Fi={12Fi1+1(i=1)(i>1)
存在通项 F i = 2 i − 1 F_{i}=2^i-1 Fi=2i1
那么对于原棋盘的每一个空段贪心填补即可。

小结

  1. 思考适当结合所学算法。例如今天的 T 2 T2 T2 在形式上类同 CRT。应该尝试思考如何在形式上转化使得原问题的形式像 CRT 靠近。

  2. 检查特殊情况。最好在考场写代码的时候就将思考到的特殊情况记录下来。写完容易忘。一定要检查!

  3. 开场看完所有题目的题面。

24oi 2023.8.24

首先这一场的 T1,T3 是两道非常简单的题目。

T2

容易想到一个状态数为 n 2 n^2 n2 的 DP 做法。设 F i , j F_{i,j} Fi,j 表示考虑前 i i i 个数,最后一个数被改成 j j j,前 i i i 个数改成不降的最小代价。状态数 n 2 n^2 n2 的保证是:存在一种最优方案,使得每一个位置最终的数都是原来的 n n n 个数之一(考虑任取一种最优解,然后进行调整)。

考场做法(在树上为错解,但序列上是正确的)。

考虑对于原始序列 a a a a a a 升序排序后为 b b b,贪心构造目标序列 c c c,最小化 ∑ ∣ a i − c i ∣ \sum |a_i-c_i| aici。由上述的结论有存在一种 c c c 的构造形如若干个 b 1 b_1 b1 后接若干个 b 2 b_2 b2 ⋯ \cdots 后接若干个 b n b_n bn。那么先将 c [ 1 , n ] c[1,n] c[1,n] 抬升到 b 1 b_1 b1。考虑抬升到 b 2 b_2 b2 的区间一定是抬升到 b 1 b_1 b1 的一个后缀。其后依次类推。

对于 i i i 位置考虑后缀 a [ i : ] a[i:] a[i:],最大能使其更优的抬升量为 p p p。考虑如何确定 p p p。有如果存在 a [ i : ] a[i:] a[i:] 的前缀 a [ i : j ] a[i:j] a[i:j] 满足其中 < p < p <p 的个数 > > > a [ i : j ] a[i:j] a[i:j] > p >p >p 的个数,那么 i i i 抬升到 p p p 是不优的。

发现在上述的这种情况中,将 a [ i : j ] a[i:j] a[i:j] 的抬升量向下调整 − 1 -1 1 更优。这样对于 a [ j + 1 : ] a[j+1:] a[j+1:] 的限制更松:整体答案不会更劣。故得证。

那么有 c i = m a x j ≤ i p j c_i=max_{j\le i}p_j ci=maxjipj。故快速确定 p i p_i pi 即可。这个是可做的。无法扩展到树上。

正解

颠覆常识的 DP 优化。其基于最开始说的 n 2 n^2 n2 的 DP。事实上,其不依赖值域取到 n n n 个数的值域:也就是说,其基于的是暴力 O ( n V ) O(nV) O(nV) 的 DP。

沿用 F i , j F_{i,j} Fi,j j j j 取遍整个值域。考虑数组 G i G_i Gi G i , j G_{i,j} Gi,j 表示 min ⁡ k ≤ i F i , k \min_{k\le i}F_{i,k} minkiFi,k
结论: G i G_i Gi 是一个 ∣ 斜率 ∣ |斜率| 斜率 不升的下凸壳。

如图所示:当 p 1 < p 2 p_1<p_2 p1<p2 G i + 1 G_{i+1} Gi+1 显然仍然满足凸壳性质。当 p 2 < p 1 p_2<p_1 p2<p1 p 2 p_2 p2 之前部分斜率绝对值变大,之后的部分斜率绝对值变小,同样满足凸壳性质。由于我们维护的是前缀 min ⁡ \min min,所以在后面有斜率为 0 0 0,不会有后面翘起来的情况。

如何快速维护凸壳和最优 DP 决策点?考虑一种神仙做法:使用堆。堆中存储所有凸壳的拐点。关于刻画斜率:由于斜率绝对值单调不升,那么通过将同一个拐点多次插入堆模拟斜率。具体的,我们令堆中两个相邻位置构成的斜线 [ x i , x i + 1 ] [x_i,x_{i+1}] [xi,xi+1] 的斜率为堆中 ≥ x i + 1 \ge x_{i+1} xi+1 的拐点个数。设插入 v v v,我们考虑如何设计转移:

  • v ≥ q . t o p ( ) v\ge q.top() vq.top()
    直接将 v v v p u s h push push 进入 q q q 即可。答案不变。
  • v < q . t o p ( ) v< q.top() v<q.top()
    答案增加 q . t o p ( ) − v q.top()-v q.top()v。同时凸壳中 ≥ v \ge v v 的部分斜率都 + 1 +1 +1,那么需要弹出最大的拐点(相当于给 ≤ q . t o p ( ) \le q.top() q.top() 的部分斜率 + 1 +1 +1),然后 p u s h push push 两次 v v v,相当于给凸壳中 ≤ v \le v v 的部分斜率 − 2 -2 2

容易拓展到树上。

24oi 2023.8.25

T1

思维水平不高导致的。
满足 a 1 ≤ a 2 ≤ a 3 ≤ ⋯ ≤ a n a_1\le a_2\le a_3\le \cdots \le a_n a1a2a3an,等价于
a 1 ≤ a 2 a 2 ≤ a 3 ⋮ \begin{aligned} a _1\le a_2\\ a_2\le a_3\\ \vdots\\ \end{aligned} a1a2a2a3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值