FJOI2020D1T2(圆方树+启发式合并)

题意简述:

给定一张\(n\)个点\(m\)条边的无向图,每个点上面有颜色\(c_i\),求把每个点割掉后,图中会有多少对颜色相同且不连通的点对.

\(n,m,c_i \leq 5e5\)

时隔一年口胡一下这道题,也不知道有没有假掉

  • 由题面可以看出和联通性相关,考虑建一颗圆方树,设\(cnt_{u,co}\)\(u\)为根的子树内,颜色为\(co\)的有多少个点.(以下的点均指原图中存在的点,即圆点)
  • 考虑设\(F_u = \sum cnt_{u,co} * (sum_{co} - cnt_{u,co})\),则答案即为\(F_{wson_u}\)减掉\(u\)节点的贡献再加上轻子树的贡献,由于轻子树的贡献都可以暴力算.我们以下着重考虑如何继承重儿子.
  • 考虑计算轻儿子间的贡献,考虑启发式合并,类似于点分治,我们先递归一遍它的子树,把在该子树存在的每种颜色的总点数减掉它子树内存在的点数,然后每到一个点,就加上它的颜色可以贡献到的点数.(这样做是为了避免算重).
  • 仍考虑用启发式合并维护\(cnt,f\),\(cnt\)数组的维护是显然的,重儿子继承,轻儿子暴力即可.考虑\(f\)数组如何继承.考虑\(f_{wson_u} -> f_{u}\),我们要减掉重儿子与轻儿子之前互相贡献的点对,这个我们仅需先保存重儿子的\(cnt\)数组,然后暴力递归轻儿子,每递归一个点,就减掉该点颜色与重儿子会产生贡献的点对的数量.然后继承重儿子的\(cnt\)数组,得到\(cnt_{u,co}\),接着我们继续遍历轻儿子,每遍历一个点,设其颜色为\(c\),就加上\(sum_{c} - cnt_{u,c}\).这样就可以继承得到正确的\(f\)数组.
  • 时间复杂度\(O(nlogn)\)
    我也知道大部分人应该会觉得我不知所云,我也这么觉得

匆忙口胡的,如果哪里假了,跪求大神指出

posted @ 2021-03-11 20:34  y_dove  阅读(136)  评论(0编辑  收藏  举报