【浙江集训】wander

题目描述

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

行走的伪代码如下:

count = 0

bool 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 -1

DFS( u, -1 )

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

  • x y之间修建一条道路,若此前 x y之间有路径相连则无视此次操作
  • x y之间存在一条直接相连的道路,则去掉之
  • 询问从 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) 中总共就恰好是 u v的路径长度。

注意这一项

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时,有可能将一个虚儿子变成重儿子,此时需要对 extra link 做出一些调整

    • splay 时需要对 extra 做出一些调整
    • 加边时需要对 extra 做出一些调整
    • 删边时需要对 link 做出一些调整
    • 剩下任意的操作都不会对 extra link 造成影响。
      于是子树大小求出来了,剩下的就是LCT的常规维护了。

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值