题目
有点复杂放个 链接。
分析
容易看出这个复制是假的,本质上就是操作序列的所有子集,于是考虑每加入一次操作所带来的贡献。
不妨记第 \(p\) 次 \(MODIFY\) 区间为 \([L,R]\),\(f_u\) 为 \(u\) 结点的所有情况 \(tag\) 之和。
做题的时候突然发现这个 \(MODIFY\) 和我日常写的不一样因此还想错了一会。。。。
- 若结点 \(u\) 未被遍历到,此次操作对结点本身没有影响,因此有 \(f_u\leftarrow f_u\times 2\)。
- 若结点 \(u\) 被遍历到且被修改,此次操作对结点 \(tag\) 直接赋值为 \(1\),因此有 \(f_u\leftarrow f_{u}+2^{p-1}\)。
- 若结点 \(u\) 被遍历到且进行了 \(PUSHDOWN\) 操作,显然有 \(f_u\leftarrow f_u\)。
- 若一个结点被遍历到且 \([l_u,r_u]\bigcap [L,R]=\emptyset\),此时结点 \(tag\) 取决于结点 \(u\) 到根节点 1 是否有 \(tag=1\),本题难点就在于此,接下来会进行细致讨论。
不妨记 \(g_u\) 为结点 \(u\) 到根节点 1 有 \(tag=1\) 的方案数,具体和上述一样也要进行讨论:
- 若结点 \(u\) 未被遍历到且 \([l_u,r_u]\bigcap[L,R]=\emptyset\) 此次操作对结点本身没有影响,因此有 \(g_u\leftarrow g_u\times 2\)。
- 若结点 \(u\) 未被遍历到且 \([l_u,r_u]\bigcap[L,R]=[l_u,r_u]\),此时结点 \(u\) 到根节点 1 有被修改的结点,因此有 \(g_u\leftarrow g_u+2^{p-1}\)。
- 若结点 \(u\) 被遍历到且被修改,此次操作对结点 \(tag\) 直接赋值为 \(1\),因此有 \(g_u\leftarrow g_{u}+2^{p-1}\)。
- 若结点 \(u\) 被遍历到且进行了 \(PUSHDOWN\) 操作,显然有 \(g_u\leftarrow g_u\)。
- 若一个结点被遍历到且 \([l_u,r_u]\bigcap [L,R]=\emptyset\),一路 \(PUSHDOWN\) 下来结果不变,因此有 \(g_u\leftarrow g_u\times 2\)。
因此接下来可以直接用线段树维护即可,只有一个地方需要用到懒标记写起来十分简单啊。
代码简单不放了。