zoukankan      html  css  js  c++  java
  • 做题笔记

    为了监督自己做题时写思路以集中注意力,从而提高效率,同时简单记录解法,防止以后看不懂自己代码特开此文。

    只记录简单做法,为防止长度过长加载速度慢,所以就不贴代码了,反正到处都存了

    CF1059E Split the Tree

    简单 2400 的题,做题时比较浮躁,静不下来,做了比较久。

    考虑到每个点必然包含在一条垂直路径,根节点必然是垂直路径的顶端。

    定义 f[i] 表示以 i 号点为垂直路径顶端点,i 的子树内的节点全覆盖的最少垂直路径数量。

    显然满足

    (sum_{v in son_x} f_v) <= f_x <= (sum_{v in son_x} f_v) + 1 即要么单飞,要么与下面某条路径合并

    转移即判断能否找到一个单飞转移点与当前点形成路径满足条件。

    由此可知,单飞的越晚越优,即能不单飞就不单飞,既把单飞机会留给之后使转移更多,又让当前位置答案更小

    由此发现,当答案最优时,单飞与否的状态也是不劣的

    明显,当确定一个点单飞后,做一个差分维护是否单飞

    可以倍增解决。

    复杂度 (O(n log n))

    [清北学堂] 校门外的树

    研究标程把这道题弄明白了,于是来写一篇题解。

    题意:

    询问一个区间内的元素的最小差值。

    分析本题,发现能够对答案产生贡献的数对具有 (n^2) 个,但是其中存在大量的无用的数对状态。

    举个例子,对于点 (i,j) ,满足 (h_i < h_j) ,则发现满足 (k > j , h_j < h_k)(k) ,都是无法与 (i) 对任何一个区间的答案产生贡献的。因为他离 (i)(j) 远,又没有 (j) 贡献答案优秀。

    类似地,我们考虑能否进一步减少我们的有用的数对数量。

    考虑 (k>j , h_k < h_j) ,发现这样的一些 (k) 并不完全可能与 (i) 产生贡献,因为这些数有可能与 (j) 组成数对会答案产生更优秀的贡献。

    简单分析可以发现,当 (h_k < (h_j + h_i) / 2) 时,(i,k) 才不一定劣。

    按照上述分析不断迭代下去,容易发现,对于每个 (i) ,最只有 (log M) 个((M) 为值域) (j) 满足 (j > i) 且与 (i) 组成数对不一定劣。

    同理对 (j > i , h_j < h_i)(j) 寻找不一定劣的数对。

    因此有用的数对个数就被压缩到了 (log M)(M) 为值域) 对。

    考虑寻找这些数对。只用开一棵动态开点线段树从后往前扫一遍,每次寻找满足不一定劣值域范围的最近的位置就好了。

    找到数对后,离线询问,左端点从大到小排序扫一遍,求符合范围的数对权值最小值,用树状数组维护一下就好了。

    CF1451F Nullify The Matrix

    显然这是一场会结束的游戏,因为路径总是从左上角到右下角,而开头总会减去正整数

    考虑使用 SG 函数来分析

    考虑类比 Nim 游戏,按照一定规则分类,将异或值做权。
    若所有类的值不全为 0 且先手总是可以将所有类变为 0 则先手必胜。

    对于初格,只能减,则只要找到包含该类二进制最高位元素即可
    对于非初格,任意元素均可实现

    发现按左斜线分类恰能满足

    CF1451E Bitwise Queries

    询问 n - 1 次,我们可以知道任意两个元素之间的异或值

    通过知道任意两个数的 & 值,我们就可以求出他们的 | 值

    (((x_1) | (x_2)) & ((x_2) | (x_3))) ^ ((x_1) & (x_3)) ^ ((x_1) & (x_2) & (x_3)) = (x_2)

    n + 2 次

    E1 solved

    显然,要么 a 是排列 , 要么存在两个元素相同

    若存在两个元素相同,& 运算求得,然后异或带回即可。

    若 a 是排列 , 则必然有 x_1 ^ x_i = n - 1 的位置 , 任选一个 x_j

    (x_2) = ((x_1) | (x_2)) & ((x_2) | (x_3))

    E2 solved

    CF1476F Lanterns

    dp , 考虑这样一个转化 , 钦定第一个没被照亮的灯后面都不会被照亮。

    扫了一眼题解,说是把可行性转化为最优性。

    那么定义 (f_i) 表示决策前 (i) 个点 , 最多能够覆盖多长的前缀

    (f_i >= i) , 则 (i) + 1 号灯往右照更优

    (f_i < i) , 则 (i) + 1 号灯可以继续往前照 , 等待未来往回照
    也可以往回照 , 二分查找转移点(f数组具有单调性) , RMQ 转移。

    总结一下 , 此题难点有且仅有将可行性转化为最优性进行 dp 。

    类似的 , 市面上同样存在将可行性转化为计算方案数的题目 , 如:

    CF1043F Make It One
    这就是一道将可行性转化为方案数以方便使用容斥计算方案是否存在的题目。

    但并非所有的可行性 dp 问题都需要转化 , 如:

    CF1539E Game with Cards
    这就是一道通过简化状态 , 以及大量预处理和数据结构来降低复杂度的题目。

    对比发现 , dp 的状态是核心 , 在对 dp 优化时应该优先考虑状态。

    或许可以将所有 dp 视为可行性 dp , 而 dp 里面存储的值需要满足无后效性的特点。
    存在与否显然满足无后效性。而本题中,最多能覆盖多长的前缀,在第一个转化下具备了无后效性。
    那么状态的信息更为丰富之后,转移起来自然更为简单。
    所以在 dp 时 , 不妨将一些无后效性的信息全部塞进 dp 的内容中。
    大概就和 CSP2019 划分 类似。

    CF1526E Oolimry and Suffix Array

    大概是这份笔记目前最简单的一道了

    (s_i) < (s_j)(a_i) == (a_j) 当且仅当 (s_{i + 1}) < (s_{j + 1}) ((s_i)(i) 号元素的排名)。

    只用确定使用了多少种字符

    按 rk 的顺序遍历一遍 , 可判断出相邻两种是 < 还是 <= 的关系。

    枚举有几种字符 , 组合数算一下就好了。

    CF1325F Ehab's Last Theorem

    考虑建 dfs 树

    一个点只会往下连 sq - 1 条边 , 否则就会形成大小为 sq 的环

    否则随便选点建独立集 , 则每次最多往上排除 sq 个点 , 至少排除 sq 次 , 所以必然有大小为 sq 的独立集。

    很有意思的一道题

  • 相关阅读:
    VBA基础一:对象、属性、方法、变量
    js画吊线图
    C++读取硬盘物理序列号-非管理员权限
    什么是句柄?
    2020年WIN7系统的几个问题处理
    静态分析:IDA逆向代码段说明 text、idata、rdata、data
    入门级汇编语法句读
    Ollydbg 单步跟踪F8
    IDA使用之旅(四)
    CSP认证201409-1-相邻数对-(Java)100分
  • 原文地址:https://www.cnblogs.com/Reanap/p/14999706.html
Copyright © 2011-2022 走看看