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])来维护,于是我们就做完了

  • 相关阅读:
    Docker运行nginx文件服务器详细配置
    containerd 使用
    【转】Oracle将以特定分隔的字符串转成表格的方法(用于类似游标的遍历)
    我的博客园的定制化配置v20201229
    李叫兽-文案创意模板
    小程序海报最佳实现思路,可视化编辑直接生成代码使用
    X型文案和Y型文案,李叫兽教你如何减少文案中的“自嗨现象”
    【运营手册2020年12月】
    软件研发的原则
    《营销的16个关键词》笔记
  • 原文地址:https://www.cnblogs.com/bcoier/p/11618363.html
Copyright © 2011-2022 走看看