• 小清新数据结构题


    首先我们要发现一个性质,对于每一棵树,我们换了一个根(把原本根的某个儿子(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])来维护,于是我们就做完了

  • 相关阅读:
    Mootools遮罩层练习(原为网上的jquery写法)
    Notepad++ c编译环境 64
    Apache添加多端口
    数据库权限分配(远程共享数据库)(mysql)
    Zend studio13 导入已有php文件夹
    按钮js跳转到非表单提交页
    Sql case when 小例
    php 获取数组中的key值
    knit使用安装 ecstore knit位置 及调用路径
    python数据库操作
  • 原文地址:https://www.cnblogs.com/bcoier/p/11618363.html
Copyright © 2020-2023  润新知