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 的概率,转移的话可以根据定义以及变化列出以下式子:
这个可以直接使用 \(4\times 4\) 的矩阵维护,最后的答案就是 \(f_1+f_3\)。
但是为什么很多题解都拿的 \(3\times 3\) 的矩阵呢?
我们可以注意到,最后的答案就是 \(f_1+f_3\),然后再自己观察一下两个的转移的式子,就可以发现可以将两个式子合并到一起,于是可以直接维护一个 \(3 \times 3\) 的矩阵了。
具体地,将 \(f_1\) 状态设为 自己的 tag=1,祖先的 tag 任意的概率,其余不变,然后式子大概长这样:
然后可以使用 \(3\times3\) 的矩阵维护了,也可以根据 \(f_0 + f_1+f_2 = 1\) ,在矩阵中维护两个状态 + 一个单位元。
因为 \(4\times4\) 的可以直接过,于是 \(3\times 3\) 代码没写,所以如果 \(3\times3\) 的式子有问题可以与我联系。