Luogu6630 [ZJOI2020] 传统艺能

2023.6.10 UPD: 3 * 3 的式子原来有笔误,感谢 灰鹤在此llzer 的指出。

有一棵广义线段树,每个节点有一个 \(m\) 值。一开始 tag 数组均为 \(0\),Bob 会执行 \(k\) 次操作,每次操作等概率随机选择区间 \([l, r]\) 并执行 MODIFY(root,1,n,l,r);
最后所有 Node 中满足 tag[Node]=1 的期望数量。
\(n \le 2\times 10^5\)


  看着题解想锤人的题。。。

  很多题解都不讲清状态的设计,以及为什么只要一个 \(3\times3\) 的矩阵,为什么状态可以这么设计,于是自行研究了一个 \(4\times 4\) 的矩阵的做法才明白原因。于是这个题解讲一个比较好理解的方式。

  首先,考虑根据期望的线性性计算答案,计算每个节点最后有 tag 的概率,比较显然的事情就是 tag 只有两种:祖先的 tag(是否存在一个祖先的 tag = 1) 和自己的 tag。接着我们可以只记录这两种 tag,并将每次操作的节点分类:

  • A. 父亲区间和操作区间没有交集:什么也不会发生变化。

  • B. 父亲区间被操作区间包含:祖先的 tag = 1,自己的 tag 不变。

  • 父亲区间和操作区间有交(但是不被包含)

    • C. 自己与操作区间没有交集:自己的 tag |= 祖先的 tag, 祖先的 tag = 0。
    • D. 自己区间被操作区间包含:祖先的 tag = 0, 自己的 tag = 1。
    • E. 自己区间和操作区间有交:祖先的 tag = 自己的 tag = 0。

  然后按照编号 ABCDE 计算方案数。

关于方案数的计算,我们可以发现,单个节点与操作区间 没有交集/被包含/没有被包含但是有交集 的概率是比较好计算的。
那么 \(A,B\) 可以从父亲节点继承过来,\(C\) 就是自己的没有交集的概率-父亲没有交集的概率,\(D\) 就是自己被包含的概率-父亲被包含的概率,最后一个,\(E =1-A-B-C-D\) 即可。

  之后魔幻的事情就来了,大部分题解都直接说维护一个 \(3\times3\) 的矩阵然后搞搞搞搞搞,甚至有的没有讲清状态的定义,令人一脸蒙 B,看了半年(尤其是式子比较复杂,还不如自己推一推,于是我就推了大半天才明白)。

  最朴素直接的想法应该是设 \(f_0, f_1, f_2, f_3\) 表示 祖先和自己 tag 都为 0 、只有自己的 tag = 1、存在一个祖先 tag = 1、自己 tag = 1 并且存在一个祖先 tag = 1 的概率,转移的话可以根据定义以及变化列出以下式子:

\[\left\{ \begin{aligned} f'_0 &= Af_0 + Cf_0 + E(f_0 + f_1 + f_2 + f_3)\\ f'_1 &= Af_1 + C(f_1+f_2+f_3)+D(f_0+f_1+f_2+f_3)\\ f'_2 &= Af_2 + B(f_0 + f_2)\\ f'_3 &= Af_3 + B(f_1 + f_3) \end{aligned} \right. \]

  这个可以直接使用 \(4\times 4\) 的矩阵维护,最后的答案就是 \(f_1+f_3\)

  代码

  但是为什么很多题解都拿的 \(3\times 3\) 的矩阵呢?

  我们可以注意到,最后的答案就是 \(f_1+f_3\),然后再自己观察一下两个的转移的式子,就可以发现可以将两个式子合并到一起,于是可以直接维护一个 \(3 \times 3\) 的矩阵了。

  具体地,将 \(f_1\) 状态设为 自己的 tag=1,祖先的 tag 任意的概率,其余不变,然后式子大概长这样:

\[\left\{ \begin{aligned} f'_0 &= Af_0 + Cf_0 + E(f_0 + f_1 + f_2)\\ f'_1 &= Af_1 + Bf_1 + C(f_1+f_2)+D(f_0+f_1+f_2)\\ f'_2 &= Af_2 + B(f_0 + f_2)\\ \end{aligned} \right. \]

  然后可以使用 \(3\times3\) 的矩阵维护了,也可以根据 \(f_0 + f_1+f_2 = 1\) ,在矩阵中维护两个状态 + 一个单位元。

  因为 \(4\times4\) 的可以直接过,于是 \(3\times 3\) 代码没写,所以如果 \(3\times3\) 的式子有问题可以与我联系。

posted @ 2022-02-04 16:27  Werner_Yin  阅读(72)  评论(1编辑  收藏  举报