zoukankan      html  css  js  c++  java
  • P3920 [WC2014]紫荆花之恋

    题目链接

    耗时4.5h的大工程。

    这题真的不难

    树上路径问题首先想点分治。并且这道题需要支持动态加叶子。如果动态加叶子的话,可能会使得点分数不够“平衡”。我们可以模仿 K-D Tree 的方法(类似替罪羊树),如果某个叶子节点占其父亲的 (siz) 的比值超过了 (alpha),那么我们就将这个子树暴力拍扁,重新构建。由于一次暴力拍扁是 (O(nlog^2n)) 的,因此我们的 (alpha) 值需要设得稍微大一些(比如 (0.8))。

    具体来说,这道题要对新加的点 (i),找到符合 (dis(i,j) <= r_i + r_j) 的所有 (j)。我们考虑在 (i,j) 路径经过的分治重心上计算贡献,则有:

    [dis(i, rt) + dis(j, rt) <= r_i + r_j ]

    [dis(j, rt) - r_j <= r_i - dis(i, rt) ]

    按照惯例,我们设 (f1(i)) 数组表示分治区域内各个点到分治重心 (i) 的距离 - 点权 的权值数组;(f2(i)) 数组表示分治区域内各个点到分治重心的点分树上父节点 (fa(i)) 的距离 - 点权 的权值数组,每次每层容斥求解,然后将(i) 的信息插入到 (f1), (f2) 数组里。 (f1, f2) 数组用平衡树维护。这里我用的替罪羊树(好写且常数小)。

    针对插入叶节点,我们就像上面一样一直跳点分树的 (fa),计算并更新平衡树。如果我们计算贡献的时候发现这个点在点分树上的子树不平衡,那么我们就将这个点暴力拍扁,即重新做一遍普通的点分治。

    细节比较多,比如说,显然这题要维护点分树,在拍扁以后我们可能需要把点分树的子树暴力重构,把子树和原来的父节点之间的边删除换掉。这个换边操作可以直接用 (vector) 实现,找到与 (fa) 连接的子树上的节点,更改 (vector) 里面存的编号即可。

  • 相关阅读:
    React Native之(支持iOS与Android)自定义单选按钮(RadioGroup,RadioButton)
    React Native之TextInput的介绍与使用(富文本封装与使用实例,常用输入框封装与使用实例)
    drf框架
    drf框架
    drf框架
    drf框架
    drf框架
    drf框架
    drf框架
    drf框架
  • 原文地址:https://www.cnblogs.com/JiaZP/p/13378450.html
Copyright © 2011-2022 走看看