Codeforces Round #728 (Div. 1) B Tree Array 题解

计不如人,肝败吓疯。

Description

传送门

Solution

翻译作品。

算法一

考虑固定一个根 r r r,作为序列中的第一个位置。从而,一个合法的 bfs \text{bfs} bfs 序列,就等价于从 r r r 往外扩展,每新扩展出一个节点就将其压入的序列。

看到期望逆序对数,不难想到枚举 x , y ( x > y ) x,y(x>y) x,y(x>y),并求出 x x x bfs \text{bfs} bfs 序列中比 y y y 先出现的概率。此时,我们已经三重循环地枚举了 r , x , y r,x,y r,x,y,需要 O ( 1 ) O(1) O(1) 计算其贡献。

我们从 x x x 走到根的某个儿子,将路径上的所有点依次压入栈 S 1 S_1 S1 中。同理,通过从 y y y 出发走到根的某个儿子,我们也得到了栈 S 2 S_2 S2。问题等价于:

  • 做多次操作,每次操作形如:

    • 找到两个栈的栈顶 p 1 , p 2 p_1,p_2 p1,p2
    • p 1 = p 2 p_1=p_2 p1=p2,那么我们有 w w w 的概率将它们同时弹出,也有 1 − w 1-w 1w 的概率啥也不做。
    • p 1 ≠ p 2 p_1 \neq p_2 p1=p2,那么我们有 w 1 w_1 w1 的概率弹出 p 1 p_1 p1,也有 w 2 w_2 w2 的概率弹出 p 2 p_2 p2(注意不能将它们同时弹出),也有 1 − w 1 − w 2 1-w_1-w_2 1w1w2 的概率啥也不做。
  • p 1 p_1 p1 先被弹空的概率。

首先,一个观察是, w 1 = w 2 w_1=w_2 w1=w2。原因显然: 令当前树上一共有 k k k 个可扩展的位置,那么 w 1 = 1 k w_1=\frac 1 k w1=k1 w 2 = 1 k w_2=\frac 1 k w2=k1。更进一步,无论在什么时候,弹 S 1 , S 2 S_1,S_2 S1,S2 的栈顶的概率均等。

然后,还有一个观察: 当 p 1 = p 2 p_1=p_2 p1=p2 时,此时 p 1 p_1 p1 p 2 p_2 p2 既是 x x x 的祖先,也是 y y y 的祖先;同时,两个栈要么同时弹,要么同时不弹。显然,这对最终谁先被弹完并无影响,于是我们可以忽略一切是 LCA ( x , y ) = l \text{LCA}(x,y)=l LCA(x,y)=l 的祖先的点(包含它自己),仅考虑以其为根的子树,并初始化 S 1 S_1 S1 为从 x x x l l l 的某个儿子经过的所有节点, S 2 S_2 S2 为从 y y y l l l 某个儿子经过的所有节点。

根据 w 1 = w 2 w_1=w_2 w1=w2,我们可以不考虑 w w w 的影响,从而这个贡献就是:

  • 给定两个长度为 d ( x , l ) d(x,l) d(x,l) d ( y , l ) d(y,l) d(y,l) 的栈,这里 d d d 表示两点间的距离。

  • 每次等概率地选择一个栈并将其栈顶弹出,求第一个栈被弹空的概率。

考虑 dp \text{dp} dp。令 f i , j f_{i,j} fi,j 表示,当两个栈长分别为 i , j i,j i,j 时第一个栈先被弹空的概率,很容易得到:

f i , j = f i , j − 1 + f i − 1 , j 2 f_{i,j}=\frac {f_{i,j-1}+f_{i-1,j}} {2} fi,j=2fi,j1+fi1,j

边界: ∀ l e n ∈ [ 1 , n ] ,   f 0 , l e n = 1 \forall len \in [1,n], \ f_{0,len}=1 len[1,n], f0,len=1

预处理出 f f f,得到结果的表达式

a n s = ∑ r = 1 n ∑ u = 1 n ∑ v = 1 u − 1 f d ( u , l ) , d ( v , l ) ans=\sum_{r=1}^n \sum_{u=1}^n \sum_{v=1}^{u-1} f_{d(u,l), d(v,l)} ans=r=1nu=1nv=1u1fd(u,l),d(v,l)

总复杂度 O ( n 3 ) O(n^3) O(n3),本题被解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值