【题解】Solution Set - NOIP2024集训Day2 线段树
【题解】Solution Set - NOIP2024集训Day2 线段树
https://www.becoder.com.cn/contest/5431
「CF1149C」Tree Generator™
结论:
对于括号序列的一个子段,删去所有的匹配括号之后,剩下的不匹配的括号,按顺序构成树上的一条路径。
Why?
从括号序列的构造出发。每次
(
相当于开始遍历一个点,)
相当于结束遍历一个点。删掉之后的括号序列,一定是形如
...)))((((...
的。相当于是先从一个点开始向上跳,然后一堆匹配的括号,相当于是跳过这整个子树,然后再不断向下跳。
注意到这个剩下的括号序列在树上是有顺序的。
所以其实这个路径就是就是从一开始的不匹配括号到末尾的的不匹配括号之间的路径。
推论1:
一棵树的直径即为其括号序列的任意子段的不匹配括号数量的最大值。
Why?
跟上面思路类似,可以证明树上的任意一条路径都可以被括号序列的一段子段表示。
嗯~面这是非常标准的错误做法,因为我们并不能直接用 d[ls].rans + d[rs].lans
来更新 d[p].ans
,因为中间会抵消一部分,让这个解变的更劣。
然后,就可以正式开始这道题了。
线段树上维护:(下面的这些值都应该是二元分别表示一开始 )
的数量和末尾 (
的数量。
- 当前区间内,选取一个子区间,再删去所有的匹配括号之后,剩下的不匹配的括号的数量的最大值
;- 选取的子区间左端点必须是整个区间的左端点
; - 选取的子区间右端点必须是整个区间的右端点
;
- 选取的子区间左端点必须是整个区间的左端点
- 选取整个区间的答案
;
直接用括号做好像不太好做(几乎可以断言不可做,因为根本没办法合并),所以我们要用一些性质转化合并的东西。
还是括号序列老套路:将 (
赋值为 )
赋值为 -1
。
对于一个区间
设
因为我们已经知道最后答案的形式一定是:...)))(((...
,所以我们不妨考虑枚举一下中间的断点
那么对于每一个断点
所以我们对于每个区间应该维护其每个子区间
注意题解
关于实现(push_up
里面更新都遵从:不跨过 mid;断点在 mid 左边;断点在 mid 右边。
「CF212D」Cutting a Fence
直接拿出式子:
考虑每个
先单调栈找到每个
然后对
然后又是经典套路:二分
实际上她是一次函数啊,直接解不等式就好了,不需要二分。😅
具体的,
注意一下重复元素的处理。
md,太兴奋了,打错了一个地方,看半天才看出来。😭
「SHOI2016」随机序列
考虑一个 dp。
设
上面这个 dp 挂了,但是我不知道为什么。😥
因为加法减法的出现是完全等价的,所以大多数时候在算贡献的时候就都会抵消掉,这就给我们带来了便利。
具体而言肯定只有开头的连续乘法有贡献,那么这道题就变成了计数题(其实也根本算不上。
然后就线段树维护一下区间乘积和答案,就好了。
「CF526F」Pudding Monsters
原题。
将二维问题一维化,还是挺重要的一个技巧。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话