【浙江集训】wander

来源:互联网 发布:群排名优化技术 编辑:程序博客网 时间:2024/04/27 20:04

题目描述

给出一棵包含n个点的森林。问按照以下规则行走,从u走到v的期望步数是多少。

行走的伪代码如下:

count = 0bool DFS( x, fa )    if ( x==v ) return 1    random_shuffle(e[x])    for each y in e[x]   // which means that all the order of has the same possibility to be chosen        ++count        if ( DFS( y, x ) ) return 1    ++count    return -1DFS( u, -1 )

要求实现Q个操作,包括以下三种

  • xy之间修建一条道路,若此前xy之间有路径相连则无视此次操作
  • xy之间存在一条直接相连的道路,则去掉之
  • 询问从u走到v的期望步数

n105,Q2×105


分析

首先分析一下要求的期望步数是个什么东西。
读懂伪代码后发现它实际上是一个按照随机顺序遍历这棵树,直到遇到终点。
假如我们某一步走了岔路,那么显然要遍历完这条岔路对应的整一棵子树。那么在每一个点上我们只关注终点所在子树,以及它之前遍历的有哪一些子树。
不妨记E(x)表示从x走到v的期望,当前所在的点为x,遍历的顺序为p0,p2,,pm,终点所在子树的根是y,排在第k位,sizex¯¯¯¯¯¯¯¯表示除通往y的那棵子树,其它子树大小的平均数,于是

E(x)=mk=0(P,pk=yk1i=0sizepi+E(pk)+1)(m+1)!=mk=0P,pk=yk1i=02sizepi(m+1)!+E(y)+1
E(v)=0

从总体来看,E(y)+1这一项在E(u)中总共就恰好是uv的路径长度。

注意这一项

mk=0P,pk=yk1i=02sizepi(m+1)!=mk=0P,pk=yk1i=02sizepim!m+1=mk=0k1i=02sizepik!pk+1pm1(mk)!m+1=mk=0k1i=02sizepik!m+1

由于这里取遍所有的满足pk为通往终点的点的可能的顺序,观察一下

  • k=0时,分子为0
  • k=1时,分子为2sizex¯¯¯¯¯¯¯¯
  • k=2时,分子为4sizex¯¯¯¯¯¯¯¯
  • k=m时,分子为2msizex¯¯¯¯¯¯¯¯

于是这一项实际上是

m(m+1)sizex¯¯¯¯¯¯m+1=zysizez

总的那一项,实际上就是以u为根的树,减去v为根的子树大小。

所以我们需要维护的东西就很明确了

  • 子树大小
  • 连通性
  • 支持动态加或删边

用LCT可以轻松解决后两个问题。
但是LCT怎么维护子树大小呢?
不妨记linkx表示当前形态的这棵树x代表的重链,最高的一个点的子树大小(注意这里要是指包括它本身和splay树的儿子所形成的一段重链)。extrax表示x的所有虚边连出的点它们的子树大小和。那么

  • access时,有可能将一个虚儿子变成重儿子,此时需要对extralink做出一些调整
  • splay时需要对extra做出一些调整
  • 加边时需要对extra做出一些调整
  • 删边时需要对link做出一些调整

剩下任意的操作都不会对extralink造成影响。
于是子树大小求出来了,剩下的就是LCT的常规维护了。

时间复杂度O(nlogn)
空间复杂度O(n)

0 0