zoukankan      html  css  js  c++  java
  • 小清新数据结构题

    首先我们要发现一个性质,对于每一棵树,我们换了一个根(把原本根的某个儿子(v_1)记成新的根)

    我们记这个树的权值和为sum,每个子树的权值和为(S[i]),对于每次换根,受影响的(S[i])只有根本身和(v_1),并且满足:(S[rt]->sum - S[v_1]), (S[v_1] -> S[rt])

    于是我们能惊人的发现:(sum (sum - S[i]) * S[i])是一个定值!!!

    把他拆开:(sum * sum S[i] - sum S[i] ^ 2)

    而我们要求的正是(sum S[i] ^ 2),于是我们只要维护(sum * sum S[i])

    因为我们会修改权值,发现sum值很好维护,于是我们只需要维护(sum S[i])即可

    我们假设以x为根,那么(sum S[i] = sum (dep[i] + 1) * val[i] = sum + sum dep[i] * val[i])

    若我们不用重新求dep,柿子即化为:$sum S[i] = sum + sum val[i] * dis(i, x) $

    这个式子就是动态点分治的模板了,但是我们其实还有一个问题:就是我们的那个定值((sum (sum - S[i]) * S[i]))要怎么求呢?

    我们还是对每个点分开考虑:上述柿子的意义实际上是求出所有点的子树和 * (总的子树和 - 该点子树和)

    我们分开考虑每一对点((i, j))的贡献,即两个点被分在不同集合的个数*权值之积

    于是这个式子其实可以转化为(sum_{i = 1}^nsum_{j = i+ 1}^nval[i] * val[j] * dis(i, j))

    (val[i])提前,我们得到:(sum_{i = 1} ^ n val[i] * sum_{j = i + 1} ^ n val[j] * dis(i, j))

    所以每一次修改(a[x] -> y),变化量即为((y - a[x]) *sum val[j] * dis(j, i))

    这不就是(sum S[i])吗???

    于是,我们就可以得到:

    [sum (sum - S[i]) * S[i] = sum * sum S[i] - sum S[i] ^ 2 ]

    [sum S[i] ^ 2 = sum * sum S[i] - sum (sum - S[i]) * S[i] ]

    (sum - 1)直接维护,(sum S[i])用动态点分治来维护,后面那一堆我们可以根据(sum S[i])来维护,于是我们就做完了

  • 相关阅读:
    时间:UTC; GMT; DST; CST
    python解析XML:之二 (ElementTree)
    python解析XML:之一
    Wiki使用
    java基础:java环境,第一个Java程序,java的数组
    Oracle记录(二) SQLPlus命令
    Oracle记录(一)Oracle简介与安装
    DIY ESXI虚拟化服务器再度升级ESXI6.0 (U盘安装Esxi)
    【VMware虚拟化解决方案】 基于VMware虚拟化平台VDI整体性能分析与优化
    vmware workstation 网络管理
  • 原文地址:https://www.cnblogs.com/bcoier/p/11618363.html
Copyright © 2011-2022 走看看