zoukankan      html  css  js  c++  java
  • CF1332 简要题解

    决定了……以后每场 CF/atc 都写题解好了。

    希望不会咕

    • A

    注意 (x_1=x_2) 或者 (y_1=y_2) 的时候任何该方向的移动都不合法即可,其余只需判断终点是否在范围内。

    • B

    由于 (a_ileq 1000),且都是合数,因此至少有一个质因子 (pleq sqrt{1000}leq 32)。打一下质数表发现恰好 (11) 个,对每个质数染色它的倍数即可。

    • C

    和字符串完全没关系的一题。由回文串和 border 的性质(题面里都写出来了……)可以直接判断哪些位置必须相等,并查集缩起来之后贪心决定每个块的值即可。

    • D

    比较有趣的一题,构造矩阵来 “欺骗” 写假了的 dp。思路是构造一条 (2^x) 的路径,并在终点处将它阻断,从而使较低位成为真正的答案。设 (x=2^{17}),则 (k<xleq 3 imes 10^5-k),有:

    [left[ egin{array}{ccc} x+k & k & 0 \ x & x+k & k\ end{array} ight] ]

    可以发现,dp 过程中的 (f_{2, 2}=x, f_{2, 3}=0),而真正的答案是 (k)

    • E

    将棋盘黑白染色后,设黑色格子的高度和为 (b),白色格子的高度和为 (w),考虑两种操作的本质:

    1. (b, w) 分别 (+1)
    2. (b)(w+2)

    显然操作不会改变 (|b-w|) 的奇偶性。

    对于 (nm) 是奇数的情况,最终 (|b-w|) 的奇偶性可以任意,因为黑白格子数必然不同,可以让多出来的格子任意填充。可以发现对于任意的初态都可以构造出解。

    对于 (nm) 是偶数的情况,显然黑白格子个数相同,也就是说,最终 (|b-w|) 必须为 (0)。可以发现,对于 (frac{nm}{2}) 个黑格子和 (frac{nm}{2}) 个白格子,都可以任意填充,只需要保证 (bequiv wpmod 2) 即可。用矩阵快速幂可以加速上述 dp 过程。

    • F

    并不算难的树 dp。

    (f_{i, 0/1/2}) 表示以 (i) 为根的子树,只考虑 (i) 与儿子之间的边时,(i) 点不在生成子图中/在生成子图中,但是不在独立集中/在独立集中的方案数。

    转移时枚举 (i) 点与儿子之间的边是否被选即可,需要保证每个 (1/2) 的状态只在第一次连接与儿子之间的边时被算到。注意如果儿子状态是 (0),且这条边被选,则儿子会被加入生成子图,此时还需要根据当前点的状态决定儿子是否在独立集中。转移方程详见代码。

    • G

    手玩一下(或者观察到输出总量是 (kq) 级别)可以发现,(kleq 4)

    对于 (k=3) 的情况,不妨设 (b_1, b_3< b_2),只需要在每个位置找出左右两边最近的,小于它的数即可。可以用权值线段树维护每个数最后出现的位置,注意到权值下标只需要小于某个值,即单点加整数,维护前缀最大值,因此树状数组也可以胜任。这样只有 (O(n)) 个三元组,将每个组挂在 (b_3) 的位置,做一遍扫描线即可。(b_1, b_3>b_2) 的情况是对称的。

    发现合法的 (k=4) 一定满足 (b_1, b_4in left(min(b_2, b_3),max(b_2, b_3) ight))。不妨设 (b_1geq b_4),考虑从左到右枚举 (b_4),寻找最靠右的合法 (b_1)

    由于 (min(b_2, b_3)<b_4leq b_1<max(b_2, b_3)),设 (x) 是当前位置左边最后一个满足 (a_x< b_4) 的位置,发现 (a_x=min(b_2, b_3)) 一定满足条件且最优。可以用 (k=3) 时的树状数组简单地找到 (x)

    对于 ([1, x)) 的每一个 (i),若 (b_1=a_i),则需要在它右边找到一个 (y) 使得 (a_i<a_y),即 (max(b_2, b_3)=a_y)。发现此处的 (y) 可以任意选择,只要保证 (y>i)(a_y>a_i) 即可。注意此处并没有限制 (x, y) 的位置关系,因此可以将每个候选的 (a_i) 用小根堆维护,在每一次枚举 (b_4) 的最后,判断当前位置是否可以成为堆顶 (a_i)(y)

    现在我们需要维护每一个找到 (y)(b_1=a_i),询问时找出 (i<x, a_igeq b_4)(a_i) 中,(i) 最大的一个。抽象一下,等于维护一个带权点集,支持插入新点和在一个包含左上角的矩阵中,询问权值最大的一个。

    可以直接写一棵树套树,但是常数巨大,不一定能过。

    注意到询问是两个前/后缀,因此可以用树状数组维护 (i)set 维护 (a_i)。具体地,在树状数组的每个位置,维护一个 set<pair<int, int>>,其中 first 代表树状数组该位置对应区间内,某个元素的 (a_i) 的值,second 代表它的点权。由于询问的是 first 的一段后缀,有用的 second 必然也是单调的。插入 ((a_i, i)) 时暴力删掉无用元素即可。复杂度 (Oleft((n+q)log^2 n ight)),常数和代码量都较小(就算这样我也写了 3.3K……)。

  • 相关阅读:
    python-进程池实例
    python-进程通过队列模拟数据的下载
    python-多进程模板
    python-多线程同步中创建互斥锁解决资源竞争的问题
    CentOS6.5配置网络
    解决CentOS系统Yum出现"Cannot find a valid baseurl for repo"问题
    CentOS 6.5安装图形界面
    Centos安装git
    Web前端优化,提高加载速度
    谁说写代码的不懂生活
  • 原文地址:https://www.cnblogs.com/suwakow/p/12614150.html
Copyright © 2011-2022 走看看