• ZJOI2019 minmax 搜索


    给定一棵有根树 (T),根节点深度为 (1),每个节点的深度为其父亲的深度 (+1),每个叶子节点的权值为其编号,现定义每个非叶节点的权值:

    • 对于深度为奇数的非叶节点,其权值为其子节点的权值最大值。
    • 对于深度为偶数的非叶节点,其权值为其子节点的权值最小值。

    然后我们得到根节点的权值 (W)

    对于一个叶子节点的集合 (S),我们现给集合 (S) 的点分配一个新权值 (w_i) 后,使得按照上述规则计算中 (W) 的权值改变,定义这个分配 (w_i) 的方案的权值为 (max_{iin S}|i-w_i|)(w(S)) 为所有方案中最小的权值。

    设叶子节点数为 (m),对于所有的 (2^m-1) 个叶子节点集合,设 (f(k)) 为有多少个集合满足 (w(S)=k),给定 (L,R),求 (f(L)+f(L+1)+...+f(R))

    答案对 (998244353) 取模。

    ( m Sol:)

    嘴巴 AC 一下...代码枯了

    观察到答案要么变大要么变小。

    如果答案要变小,那么我们肯定是将集合内所有元素都减去 (k)

    然后统计有多少个集合可以使得答案变化。

    不难发现我们求的大概是 (sum f(x)[xle k]),设为 (g(k)),差分一下就可以得到答案了。

    但是 (g(k)) 直接求不太好求,因为实际上我们可以求出来的是有多少个集合满足变小后合法,变大后合法,存在一些集合满足变大/变小都合法。

    他们是要减去的。

    事实上那些集合满足变大/变小均合法也很好算,Dp 的时候维护 (4) 个数组就可以了 (f_{u,0/1,0/1}) 表示变大的情况下大于/小于,变小的情况下大于/小于。

    于是就得到了一个 (mathcal O((R-L)cdot n)) 的算法。

    具体 check 大概是对于某个 (k),对于变小的情况,假设 (i-k<W),那么设为 (0),否则设为 (1),那么取 (min) 就是按位 (&),取 (max) 就是按位或,大于的情况同理。

    进一步优化就考虑直接维护 (mathcal O(n)) 个数组,设 (f_{u,0/1,0/1,k}) 表示对于 (k),考虑到点 (u)((0/1, 0/1)) 情况下的答案。

    不难发现转移其实是将数组对应部分乘起来并做加法的过程。

    初始值也是插入在某个状态的一段区间内。

    用线段树合并维护即可,要维护加法标记和乘法标记,复杂度 (mathcal O(nlog n)),空间复杂度 (mathcal O(nlog n)),会附带 (4) 的常数。

    代码枯了。

  • 相关阅读:
    Integer判等的陷阱:你知道Integer内部高速缓冲区IntegerCache吗?
    Unicode 是不是只有两个字节,为什么能表示超过 65536 个字符
    java中Char到底是什么格式的编码
    Java中char和String 的深入理解
    关于serialVersionUID的说明
    Java中的instanceof和isInstance基础讲解
    编码(1)学点编码知识又不会死:Unicode的流言终结者和编码大揭秘
    知识图谱和图卷积(贪心学院)——学习笔记
    索尼相机,索尼W35,Sony Cyber-shot DSC-w35
    高斯分布与高斯过程梳理
  • 原文地址:https://www.cnblogs.com/Soulist/p/13638263.html
Copyright © 2020-2023  润新知