Petrozavodsk Programming Camp 部分题解

PtzWC 2018, Yandex Cup

F. Shuffle

  • 将标号变为 0 ∼ n − 1 0 \sim n - 1 0n1,则
    shuffle ( s ) = s 0 s 2 … s n − 2 s 1 s 3 … s n − 1 \text{shuffle}(s) = s_0s_2\dots s_{n-2}s_1s_3\dots s_{n - 1} shuffle(s)=s0s2sn2s1s3sn1
  • p i p_i pi 表示 i i i 变换后得到的标号,则
    p i = { i 2 , if  i  is even i − 1 2 + n 2 , if  i  is odd p_i = \begin{cases} \frac{i}{2}, \text{if}\ i\ \text{is}\ \text{even} \\\frac{i - 1}{2}+\frac{n}{2},\text{if}\ i\ \text{is}\ \text{odd}\end{cases} pi={2i,if i is even2i1+2n,if i is odd
  • i → p i i \to p_i ipi 构成若干个轮换,通过 KMP \text{KMP} KMP 可以求出每个轮换上 s s s 在一个周期(轮换的长度)内逆序循环位移能得到 t t t 的位移次数(注意不止一个,且最少的不一定是最后答案的限制条件),可以得到若干同余方程的限制形式。
  • 注意到:
    • i = n − 1 i = n - 1 i=n1 时, p i = i p_i = i pi=i
    • 0 ≤ i < n − 1 0 \le i < n - 1 0i<n1 时, i ≡ 2 p i ( m o d    ( n − 1 ) ) i \equiv 2p_i (\mod (n - 1)) i2pi(mod(n1))
  • 通用的可能思考方向 ∑ p i = n ( p i ≥ 0 ) \sum p_i = n(p_i \ge 0) pi=n(pi0) p i p_i pi 至多有 O ( n ) \mathcal O(\sqrt n) O(n )
  • 由欧拉定理 2 φ ( n − 1 ) ≡ 1 ( m o d    ( n − 1 ) ) 2^{\varphi(n - 1)} \equiv 1(\mod (n-1)) 2φ(n1)1(mod(n1)) Ord n ( 2 ) ∣ φ ( n − 1 ) \text{Ord}_n(2)|\varphi(n - 1) Ordn(2)φ(n1),故轮换的长度均为 φ ( n − 1 ) \varphi(n - 1) φ(n1) 的约数,我们可以将同种长度的限制条件整合到一起,不同的环长至多有 O ( n ) \mathcal O(\sqrt n) O(n ) 种,因而总时间复杂度 O ( φ ( n − 1 ) n ) \mathcal O(\varphi(n - 1)\sqrt n) O(φ(n1)n )
  • Code

I. ≤ or ≥

  • 若只是简单地取中位数,可能会被刻意构造使得某个栈内元素始终无法取出。
  • 考虑给深度为 d d d 的栈赋一个权重 f ( d ) = a d f(d) = a^d f(d)=ad,每次取加权中位数,则每次总的权重会变为原来的 1 2 + f ( d − 1 ) 2 f ( d ) = a + 1 2 a \frac{1}{2}+\frac{f(d-1)}{2f(d)}=\frac{a+1}{2a} 21+2f(d)f(d1)=2aa+1,总移动次数为 log ⁡ 2 a a + 1 ( n a k ) \log_{\frac{2a}{a+1}}(na^k) loga+12a(nak),通过计算可知 a = 3 a = 3 a=3 时最优。
  • Code

PtzWC 2022. Day 1. Kyoto U Contest 2

G. Game with Balls and Boxes

  • 首先可以单独考虑每个轮换,轮换间元素的交换显然是无用的。
  • 在某个轮换中,若所有盒子均在第一次打开,直接结束;否则若第一次打开的盒子被分成几段,每段最左边的盒子和没有被打开的盒子均需要在第二次被打开,由此做线性 DP 即可。
  • Code

K. King’s Palace

  • 考虑 meet-in-the-middle \text{meet-in-the-middle} meet-in-the-middle
  • n 1 = n − ⌊ n 3 ⌋ n_1 = n - \lfloor \frac{n}{3} \rfloor n1=n3n n 2 = ⌊ n 3 ⌋ n_2 = \lfloor \frac{n}{3} \rfloor n2=3n,暴搜前 n 1 n_1 n1 面墙,将与之冲突的后 n 2 n_2 n2 面墙的刷法用 3 n 2 3n_2 3n2 位二进制数 s s s 压缩,方案数记为 f s f_s fs,对 f s f_s fsFMT,再爆搜后 n 2 n_2 n2 面墙,记这 n 2 n_2 n2 面的刷法对应的二进制数为 s ′ s' s,则将答案加上 f ( 2 3 n 2 − 1 ) ⊕ s ′ f_{(2^{3n_2} - 1) \oplus s'} f(23n21)s
  • 总时间复杂度 O ( n 1 3 n 1 + n 2 3 n 2 + 3 n 2 2 3 n 2 ) \mathcal O(n_13^{n_1}+n_23^{n_2}+3n_22^{3n_2}) O(n13n1+n23n2+3n223n2)
  • Code

PtzWC 2022. Day 2. KAIST Contest + KOI TST 2021

A. Points

  • 碰到 max ⁡ / min ⁡ \max/\min max/min 后接常数项时,可考虑取某一项的限制条件。
  • u x + v x ≥ u y + v y u_x + v_x \ge u_y + v_y ux+vxuy+vy 时,即当 u x − u y ≥ v y − v x u_x - u_y \ge v_y - v_x uxuyvyvx 时,取 u x + v x u_x + v_x ux+vx,否则取 u y + v y u_y + v_y uy+vy
  • u x − u y u_x - u_y uxuy 作为 u u u 的下标,将 v y − v x v_y - v_x vyvx 作为 v v v 的下标,将所有 u , v u,v u,v 存在一棵线段树内,则所有取 u x + v x u_x + v_x ux+vx 项的最小值相当于取一个 u u u 和一个 v v v,使得 u u u 的下标大于等于 v v v,所有取 u y + v y u_y + v_y uy+vy 项的最小值相当于取一个 u u u 和一个 v v v,使得 u u u 的下标小于等于 v v v,容易用线段树维护。
  • Code

C. AND or PLUS

  • i = x ∨ y , j = x ∨ z i = x \vee y, j = x \vee z i=xy,j=xz,则
    A i + A j < A i ∧ j + A i ∨ j ⇔ A x ∨ y + A x ∨ z < A x + A x ∨ y ∨ z A_i + A_j < A_{i \wedge j} + A_{i \vee j} \Leftrightarrow A_{x \vee y} + A_{x \vee z} < A_x + A_{x \vee y \vee z} Ai+Aj<Aij+AijAxy+Axz<Ax+Axyz
  • 固定 x , y x,y x,y,设 f ( z ) = A x ∨ y ∨ z − A x ∨ z f(z) = A_{x\vee y\vee z} - A_{x \vee z} f(z)=AxyzAxz,则上式等价于
    f ( ∅ ) < f ( z ) f(\empty) < f(z) f()<f(z)
    若存在解 ( x , y , z ) (x, y, z) (x,y,z),则存在解 ( x ∨ ( z − lowbit ( z ) ) , y , lowbit ( z ) ) (x \vee (z - \text{lowbit}(z)), y, \text{lowbit}(z)) (x(zlowbit(z)),y,lowbit(z))
  • 交换 i , j i,j i,j,同理可证,若存在解 ( x , y , z ) (x, y, z) (x,y,z),则存在解 ( x ∨ ( y − lowbit ( y ) ) , lowbit ( y ) , z ) (x \vee (y - \text{lowbit}(y)),\text{lowbit}(y),z) (x(ylowbit(y)),lowbit(y),z)
  • 可推出,若存在解 ( x , y , z ) (x,y,z) (x,y,z),则存在解 ( x ∨ ( y − lowbit ( y ) ) ∨ ( z − lowbit ( z ) ) , lowbit ( y ) , lowbit ( z ) ) (x \vee (y - \text{lowbit}(y)) \vee (z - \text{lowbit}(z)), \text{lowbit}(y),\text{lowbit}(z)) (x(ylowbit(y))(zlowbit(z)),lowbit(y),lowbit(z))
  • 因而直接枚举即可,时间复杂度 O ( N 2 2 N ) \mathcal O(N^22^N) O(N22N)
  • Code

L. Curly Pacetrack

  • 首先需要将横向和纵向的道路分开考虑,只有瓷砖内恰好有一个方向的横向道路和一个方向的纵向道路才能算 curly tiles \text{curly tiles} curly tiles
  • 以横向道路为例,每次考虑每行两个相邻已铺好瓷砖之间的瓷砖摆放方案,不难证明,根据这两块瓷砖的横向道路方向是否相同,以及两块瓷砖之间需要摆放的瓷砖数量(包含 x )的奇偶性,瓷砖摆放方案只有两种可能:
    1. 所有摆放的瓷砖均恰好有一个横向道路。
    2. 所有摆放的瓷砖只有一块不恰好有一个横向道路。
  • 第 1 种情况不需要考虑 ox 的分布,对于第 2 种情况:
    • 若所有需摆放的瓷砖的标记均为 o,无解。
    • 若需摆放的瓷砖的标记中存在 x,可令 x 所在瓷砖不恰好有一个横向道路以实现最大化 curly tiles \text{curly tiles} curly tiles
    • 不属于以上两种情况,则需要在标记不为 o 的瓷砖中选择一个使其不恰好有一个横向道路。
  • 纵向道路同理,我们需要使不恰好有一个横向道路和不恰好有一个纵向道路的瓷砖尽可能重叠,建出求二分图求最大匹配即可。
  • Code

PtzWC 2022. Day 3. Kazakhstan Contest

D. Hidden Rook

  • 当前已经确定 Rook \text{Rook} Rook 在某个矩形内,容易想到每次取矩形的中心点,通过询问划分出的四个子矩形中的某一个,就能确定 Rook \text{Rook} Rook 属于某个子矩形,将范围缩减到原有的 1 4 \frac{1}{4} 41,符合题目要求。
  • 注意到上述做法需保证每次询问的矩形长宽不等且均大于 1,在当前矩形边长较小时可能找不到合法的矩形,此处的思维难点在于可以让询问的矩形范围超出当前确定的矩形范围。
  • n , m ≤ 4 n,m\le 4 n,m4 时可以特判并对长宽分别二分,否则从矩形长宽的中点分别向左右两侧延伸,大于 1 的长和宽都至少有两种,我们再将取得的长宽进行组合,此时至少有一种组合方式使得长宽不等,故每次都至少能找到一个合法的询问矩形,更新确定矩形的范围并不需要过多的分类讨论,可以通过将长宽区间做类似集合的并和补运算实现。
  • 如果没有考虑得足够清楚本题的代码难度较大,给出的代码实现方式较为简洁可供参考。
  • Code

H. Aidana and Pita

  • 考虑 meet-in-the-middle \text{meet-in-the-middle} meet-in-the-middle
  • n 1 = ⌊ n 2 ⌋ , n 2 = n − n 1 n_1 = \lfloor \frac{n}{2} \rfloor, n_2 = n - n_1 n1=2n,n2=nn1,分别 3 n 1 , 3 n 2 3^{n_1},3^{n_2} 3n1,3n2 搜索三元组集合 L 1 , L 2 L_1, L_2 L1,L2,设 L 1 L_1 L1 中某个三元组为 ( x 1 , y 1 , z 1 ) (x_1,y_1,z_1) (x1,y1,z1) L 2 L_2 L2 中某个三元组为 ( x 2 , y 2 , z 2 ) (x_2,y_2,z_2) (x2,y2,z2),若其满足 x 1 + x 2 ≥ y 1 + y 2 ≥ z 1 + z 2 x_1 + x_2 \ge y_1 + y_2 \ge z_1 + z_2 x1+x2y1+y2z1+z2,我们需要最小化 x 1 + x 2 − z 1 − z 2 x_1 + x_2 - z_1 - z_2 x1+x2z1z2
  • 简单移项后可得:
    { a 1 = x 1 − y 1 ≥ y 2 − x 2 = a 2 b 1 = y 1 − z 1 ≥ z 2 − y 2 = b 2 \begin{cases}a_1 = x_1 - y_1 \ge y_2 - x_2 = a_2 \\b_1 = y_1 - z_1 \ge z_2 - y_2 = b_2 \\ \end{cases} {a1=x1y1y2x2=a2b1=y1z1z2y2=b2
  • 即对于每个 ( a 1 , b 1 ) (a_1, b_1) (a1,b1),找到 ( a 2 , b 2 ) (a_2, b_2) (a2,b2) 满足 { a 1 ≥ a 2 b 1 ≥ b 2 \begin{cases}a_1 \ge a_2 \\ b_1 \ge b_2\end{cases} {a1a2b1b2 a 1 + b 1 − a 2 − b 2 a_1 + b_1 - a_2 - b_2 a1+b1a2b2 最小,排序后用 BIT 维护即可,时间复杂度 O ( 3 n 2 n ) \mathcal O(3^{\frac{n}{2}}n) O(32nn)
  • Code

PtzWC 2023. Day2

D. Lonely King请添加图片描述

  • Leaf ( T ) \text{Leaf}(T) Leaf(T) 表示树 T T T 的叶结点集合, Subtree ( x ) \text{Subtree}(x) Subtree(x) 表示以 x x x 为根的子树,定义:
    f ( x ) = min ⁡ l ∈ Leaf(Subtree(x)) { c l c f a ( x ) + ∑ f ( b i ) } f(x) = \min\limits_{l \in \text{Leaf(Subtree(x))}}\{c_lc_{fa(x)} + \sum f(b_i)\} f(x)=lLeaf(Subtree(x))min{clcfa(x)+f(bi)}
  • 其中 b i b_i bi 表示 Subtree ( x ) \text{Subtree}(x) Subtree(x) 取出从 x x x l l l 的路径后所有剩余子树的根结点,最终答案为 ∑ f a ( x ) = r o o t f ( x ) \sum \limits_{fa(x) = root}f(x) fa(x)=rootf(x)
  • 考虑将每个叶节点视为直线 y = c l x + ∑ f ( b i ) y = c_l x + \sum f(b_i) y=clx+f(bi),询问即查询某个 x x x 处的最值,用李超树维护这些叶结点,当将某个结点的李超树合并给其父结点时,需要将李超树内所有直线的截距加上一个常数,可通过标记下放实现。
  • 合并同层不同结点的李超树时,采用线段树合并即可。
  • Code

PtzWC 2023. Day3

F. Sum of Numbers

请添加图片描述

  • 考虑若相邻两个数长度相差 2,将这段数字等分重新得到这两个数一定比原方案更优,因而若当前划分的数字长度为 x x x,下一个划分的数字长度只能为 x + 1 , x , x − 1 x + 1,x,x-1 x+1,x,x1
  • 考虑到总和为 n n n 的限制,合法的划分方案相当少,暴搜后用压位高精度计算即可。
  • Code

PtzWC 2023. Day4

F. Making Number

  • 显然 Z Z Z 要么等于 Y Y Y,要么存在某一位 p o s pos pos 满足 Z p o s > Y p o s Z_{pos} > Y_{pos} Zpos>Ypos,之后贪心填,因而找到 p o s pos pos 就很容易处理询问。
  • 找到 X X X 照着 Y Y Y 填可能的最长前缀,设为 t t t注意 p o s pos pos 并不具有可二分性,我们需要研究 p o s pos pos t t t 之间的关系。
  • 首先检查 p o s = t + 1 pos = t + 1 pos=t+1 是否可行,不可行检查 p o s = t pos = t pos=t。考虑到 p o s = t − 1 pos = t - 1 pos=t1 不可行等价于 Y t − 1 ≥ Y t Y_{t-1}\ge Y_t Yt1Yt, 再往前同理,故记 L T t = [ Y t ≥ Y t − 1 ] LT_{t} = [Y_{t}\ge Y_{t-1}] LTt=[YtYt1],相当于查询以 t − 1 t - 1 t1 为结尾的最长后缀 1。
  • 上述操作均可用线段树实现。
  • Code

M. Window Arrangement

  • 首先将限制改为拆去 4 − w i , j 4 - w_{i,j} 4wi,j 扇窗,最大化拆去的价值,可以得出费用流建图:
    • s s s 向每堵墙连容量为 1、费用为相邻两房间人数乘积的边。
    • 每堵墙向相邻两房间需拆出的每扇窗连容量为 1、费用为 0 的边。
    • 需拆去的每扇窗向 t t t 连容量为 1、费用为 0 的边。
  • 将房间拆点表示每扇窗是为了让建图更接近于一般概念上的二分图,此时有费用的边只在二分图一侧
  • 这种类型的图有通用的快速做法,即将边按费用从大到小排序,依据这一顺序跑匈牙利算法,容易证明其正确性。
  • Code
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值