题目传送门:LOJ #3043

题意简述:

你需要模拟线段树的懒标记过程。

初始时有一棵什么标记都没有的 \(n\) 阶线段树。

每次修改会把当前所有的线段树复制一份,然后对于这些线段树实行一次区间修改操作。

即每次修改后线段树棵数翻倍,第 \(i\) 次修改后,线段树共有 \(2^i\) 棵。

区间修改操作的伪代码如下:

和我日常写的递归式线段树完全一致。

每次询问你这些线段树中有懒标记的节点总数。

修改和询问的总个数为 \(q\),\(1\le n,q\le 10^5\)。

题解:

灵感来源自 Sooke 的题解。

考察一次区间修改操作会影响到的节点,共有 \(5\) 类:

  1. 与修改区间相交,但不包含在修改区间内部的节点(浅紫色)。

  2. 包含在修改区间内部,但其父亲不存在或不包含在修改区间内部(浅蓝色)。

  3. 与修改区间相离,但其父亲与修改区间相交(浅橙色)。

  4. 包含在修改区间内部,且其父亲也包含在修改区间内部(深蓝色)。

  5. 与修改区间相离,且其父亲也与修改区间相离(深橙色)。

将节点分为这 \(5\) 类并不是没有根据的,可以发现:

若伪代码运行到了第 \(17\) 行,则访问到的是第 \(1\) 类节点。

若伪代码运行到了第 \(14\) 行,则访问到的是第 \(2\) 类节点。

若伪代码运行到了第 \(11\) 行,则访问到的是第 \(3\) 类节点。

而第 \(4,5\) 类节点分别是第 \(2,3\) 类节点的子孙。

根据线段树的复杂度,第 \(1,2,3\) 类节点的个数均为 \(\mathcal{O}(\log n)\),而第 \(4,5\) 类节点的个数为 \(\mathcal{O}(n)\)。

接下来分析每次操作时受到影响的节点:

对于第 \(1\) 类节点,操作后它们必然无懒标记。

对于第 \(2\) 类节点,操作后它们必然有懒标记。

对于第 \(3\) 类节点,操作后它们有无懒标记取决于操作前这个节点到根的链上有无懒标记。

对于第 \(4,5\) 类节点,操作后它们不受影响。

我们考虑维护每次操作后每个节点 \(u\) 有懒标记的树的占比,即在 \(2^i\) 棵树中,节点 \(u\) 有懒标记的树的比值,记作 \(\mathrm{f}[u]\)。

同时,因为第 \(3\) 类节点需要额外信息,维护每次操作后每个节点 \(u\) 到根的路径上有懒标记的树的占比,记作 \(\mathrm{g}[u]\)。

接下来我们考虑一次操作后,每个节点的信息如何更新,注意到同类节点的更新方式是相同的:

对于第 \(1\) 类节点,一半保持原样,另一半无标记,所以 \(\left\langle\mathrm{f}[u],\mathrm{g}[u]\right\rangle=\left\langle\frac{1}{2}\mathrm{f}[u],\frac{1}{2}\mathrm{g}[u]\right\rangle\)。

对于第 \(2\) 类节点,一半保持原样,另一半有标记,所以 \(\left\langle\mathrm{f}[u],\mathrm{g}[u]\right\rangle=\left\langle\frac{1}{2}\mathrm{f}[u]+\frac{1}{2},\frac{1}{2}\mathrm{g}[u]+\frac{1}{2}\right\rangle\)。

对于第 \(3\) 类节点,一半保持原样,另一半的标记取决于 \(u\) 到根的路径,所以 \(\left\langle\mathrm{f}[u],\mathrm{g}[u]\right\rangle=\left\langle\frac{1}{2}(\mathrm{f}[u]+\mathrm{g}[u]),\mathrm{g}[u]\right\rangle\)。

对于第 \(4\) 类节点,一半保持原样,另一半标记不受影响,但到根的路径上一定有标记,所以 \(\left\langle\mathrm{f}[u],\mathrm{g}[u]\right\rangle=\left\langle\mathrm{f}[u],\frac{1}{2}\mathrm{g}[u]+\frac{1}{2}\right\rangle\)。

对于第 \(5\) 类节点,一半保持原样,另一半标记不受影响,到根的路径上的标记也不受影响,所以 \(\left\langle\mathrm{f}[u],\mathrm{g}[u]\right\rangle=\left\langle\mathrm{f}[u],\mathrm{g}[u]\right\rangle\)。

第 \(5\) 类节点的信息没有更改,第 \(4\) 类节点仅有 \(\mathrm{g}\) 有更改,因为第 \(4\) 类节点有 \(\mathcal{O}(n)\) 个,所以必须采用打懒标记的方法来维护。

而对于前 \(3\) 类,直接维护即可。

再多维护一个 \(\mathrm{Sf}[u]\) 表示 \(u\) 的子树中 \(\mathrm{f}[v]\) 值之和即可统计答案。

#include <cstdio>

typedef long long LL;
const int Mod = 998244353;
const int Inv2 = 499122177;
const int MS = 1 << 18; inline int Add(int x, int y) {
return (x += y) >= Mod ? x - Mod : x;
} int N, M; int f[MS], g[MS], Sf[MS], T[MS];
inline void P(int i, int x) {
g[i] = ((LL)g[i] * x + 1 - x + Mod) % Mod;
T[i] = (LL)T[i] * x % Mod;
}
inline void Upd(int i, int Ty) {
if (Ty) Sf[i] = f[i];
else Sf[i] = Add(f[i], Add(Sf[i << 1], Sf[i << 1 | 1]));
}
inline void Psd(int i) {
P(i << 1, T[i]);
P(i << 1 | 1, T[i]);
T[i] = 1;
}
void Build(int i, int l, int r) {
T[i] = 1;
if (l != r) {
Build(i << 1, l, (l + r) >> 1);
Build(i << 1 | 1, ((l + r) >> 1) + 1, r);
}
}
void Mdf(int i, int l, int r, int a, int b) {
if (r < a || b < l) {
f[i] = (LL)(f[i] + g[i]) * Inv2 % Mod;
Upd(i, l == r);
return ;
}
if (a <= l && r <= b) {
f[i] = (LL)(f[i] + 1) * Inv2 % Mod;
Upd(i, l == r);
P(i, Inv2);
return ;
}
Psd(i);
f[i] = (LL)f[i] * Inv2 % Mod;
g[i] = (LL)g[i] * Inv2 % Mod;
Mdf(i << 1, l, (l + r) >> 1, a, b);
Mdf(i << 1 | 1, ((l + r) >> 1) + 1, r, a, b);
Upd(i, 0);
} int main() {
scanf("%d%d", &N, &M);
Build(1, 1, N);
for (int m = 1, C = 1; m <= M; ++m) {
int op, l, r;
scanf("%d", &op);
if (op == 1) {
scanf("%d%d", &l, &r);
Mdf(1, 1, N, l, r);
C = Add(C, C);
}
else printf("%lld\n", (LL)C * Sf[1] % Mod);
}
return 0;
}

LOJ 3043: 洛谷 P5280: 「ZJOI2019」线段树的更多相关文章

  1. LOJ 3045: 洛谷 P5326: 「ZJOI2019」开关

    题目传送门:LOJ #3045. 题意简述 略. 题解 从高斯消元出发好像需要一些集合幂级数的知识,就不从这个角度思考了. 令 \(\displaystyle \dot p = \sum_{i = 1 ...

  2. 【LOJ】#3043. 「ZJOI2019」线段树

    LOJ#3043. 「ZJOI2019」线段树 计数转期望的一道好题-- 每个点设两个变量\(p,q\)表示这个点有\(p\)的概率有标记,有\(q\)的概率到祖先的路径上有个标记 被覆盖的点$0.5 ...

  3. 「ZJOI2019」线段树 解题报告

    「ZJOI2019」线段树 听说有人喷这个题简单,然后我就跑去做,然后自闭感++,rp++(雾) 理性分析一波,可以发现最后形成的\(2^k\)个线段树,对应的操作的一个子集,按时间顺序作用到这颗线段 ...

  4. LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset

    题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...

  5. LOJ 3089: 洛谷 P5319: 「BJOI2019」奥术神杖

    题目传送门:LOJ #3089. 题意简述: 有一个长度为 \(n\) 的母串,其中某些位置已固定,另一些位置可以任意填. 同时给定 \(m\) 个小串,第 \(i\) 个为 \(S_i\),所有位置 ...

  6. LOJ 3093: 洛谷 P5323: 「BJOI2019」光线

    题目传送门:LOJ #3093. 题意简述: 有 \(n\) 面玻璃,第 \(i\) 面的透光率为 \(a\),反射率为 \(b\). 问把这 \(n\) 面玻璃按顺序叠在一起后,\(n\) 层玻璃的 ...

  7. LOJ 2483: 洛谷 P4655: 「CEOI2017」Building Bridges

    题目传送门:LOJ #2483. 题意简述: 有 \(n\) 个数,每个数有高度 \(h_i\) 和价格 \(w_i\) 两个属性. 你可以花费 \(w_i\) 的代价移除第 \(i\) 个数(不能移 ...

  8. LOJ 2249: 洛谷 P2305: 「NOI2014」购票

    题目传送门:LOJ #2249. 题意简述: 有一棵以 \(1\) 号节点为根节点的带边权的树. 除了 \(1\) 号节点的所有节点上都有人需要坐车到达 \(1\) 号节点. 除了 \(1\) 号节点 ...

  9. @loj - 3043@「ZJOI2019」线段树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 九条可怜是一个喜欢数据结构的女孩子,在常见的数据结构中,可怜最喜 ...

随机推荐

  1. Linux 上传下载文件 [转]

    从服务器下载文件scp username@servername:/path/filename /tmp/local_destination例如:scp codinglog@192.168.0.101: ...

  2. Java新AIO/NIO2:AsynchronousServerSocketChannel和AsynchronousSocketChannel简单服务器-客户端

    Java新AIO/NIO2:AsynchronousServerSocketChannel和AsynchronousSocketChannel简单服务器-客户端用AsynchronousServerS ...

  3. 【BZOJ1876】[SDOI2009]SuperGCD(数论,高精度)

    [BZOJ1876][SDOI2009]SuperGCD(数论,高精度) 题面 BZOJ 洛谷 题解 那些说数论只会\(gcd\)的人呢?我现在连\(gcd\)都不会,谁来教教我啊? 显然\(gcd\ ...

  4. 洛谷 [HNOI2014]道路堵塞 解题报告

    [HNOI2014]道路堵塞 题意 给一个有向图并给出一个这个图的一个\(1\sim n\)最短路,求删去这条最短路上任何一条边后的最短路. 又事SPFA玄学... 有个结论,新的最短路一定是\(1\ ...

  5. es某个分片受损或卡在INITIALIZING状态时解决办法

    参考这篇文章 # OK last warning: you will probably lose data. Don't do this if you can't risk that. CLUSTER ...

  6. NO.9: 令operator=返回一个reference to *this

    1.令赋值操作返回一个reference to *this(除非你有个标新立异的理由,那就随大众- - )

  7. ffmpeg处理视频与声音

    1.ffmpeg将mp4分解成多张jpg图片 要在游戏中播放视频,引擎竟然不支持.琢磨了一下,干脆将视频图片提取出来,然后用Animation动画类来播放这些图片,这样也能实现播放视频的效果.还是ff ...

  8. es7预览

    哈哈,es6才刚刚掌握,就给大家介绍es7了. es7的草案其实早已经定下来了,而且更加向着java这些高级语言看齐了 chrome的高版本其实也已经对es7的部分功能实现了!! 1.数组 inclu ...

  9. Python字符编码以及循环机制介绍

    Python字符编码以及循环机制介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 身为一名运维人员就得不断的学习,那么如何身为运维的你是否已经嗅探已经很火的Python编程啦?大 ...

  10. golang数组排序算法

    冒泡排序 图 https://www.cnblogs.com/onepixel/articles/7674659.html package main import ( "fmt" ...