题目描述 一个合法的括号序列是这样定义的: 空串是合法的. 如果字符串 S 是合法的,则(S)也是合法的. 如果字符串 A 和 B 是合法的,则 AB 也是合法的. 现在给你一个长度为 N 的由‘('和‘)'组成的字符串,位置标号从 1 到 N.对这个字符串有下列四种操作: Replace a b c:将[a,b]之间的所有括号改成 c.例如:假设原来的字符串为:))())())(,那么执行操作 Replace 2 7 ( 后原来的字符串变为:)(((((()(. Swap a b:将[a,b]…
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2329 题解: Splay 类似 BZOJ 2329 [HNOI2011]括号修复 只是多了一个Replace(替换)操作, 然后就要主要lazy标记之间的影响了. 1).Replace可以直接覆盖另外两个标记, 2).当已经有Replace标记,再覆盖Invert标记时,直接把Replace标记取反即可;在覆盖Swap标记时,Replace标记不变. 代码: #include<cstdio…
[BZOJ2329/2209][HNOI2011]括号修复/[Jsoi2011]括号序列 题解:我们的Splay每个节点维护如下东西:左边有多少多余的右括号,右边有多少多余的左括号,同时为了反转操作,还要维护左边有多少多余的左括号,右边有多少多余的右括号(如果一个右括号匹配一个左括号的话).然后xjb维护一番即可... 答案是什么呢?$\lceil{左边多余的右括号数\over 2}\rceil+\lceil{右边多余的左括号数\over 2}\rceil$. #include <cstdio>…
把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和l, 最大后缀和r就可以了..答案就是(l+1)/2+(r+1)/2...用splay维护,O(NlogN). 其实还是挺好写的, 只是我傻X -------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstrin…
题面: http://www.lydsy.com/JudgeOnline/problem.php?id=2329 思路: 显然,操作4中输出补全的最小费用是关键 这决定了我们不可能在splay上只维护1-2个值. 考虑一段括号序列,将其中所有合法序列删去以后,留下的一定是形如 ))))))((( 的序列 因此首先考虑将每段区间左侧不匹配的括号数和右侧不匹配的括号数记录下来,分别为 left[l,r] 和 right[l,r] 此时除了Invert操作以外已经可以满足 但是对于Invert操作,对…
题目大意: 让你维护一个括号序列,支持 1.区间修改为同一种括号 2.区间内所有括号都反转 3.翻转整个区间,括号的方向不变 4.查询把某段区间变为合法的括号序列,至少需要修改多少次括号 给跪了,足足$de$了$3h$ 感觉这道题的思维难度比维修数列高多了 前三个操作都非常好搞,都是区间打标记 注意下推标记的顺序,子树根如果有区间覆盖标记,那么子树内所有节点的反转和翻转标记都失效了,要清空 而下传到同一节点的区间覆盖和反转翻转标记不冲突 我们下推标记时必须保证,下推后,两个子节点的状态拿来就能用…
题目链接 题意:有一个长度为 \(n\) 的括号序列,你需要支持以下操作: 将 \([l,r]\) 中所有括号变为 \(c\) 将 \([l,r]\) 区间翻转 将 \([l,r]\) 区间中左括号变右括号,右括号变左括号 求最少需要改变多少个括号才能使得 \([l,r]\) 变成合法括号序列,保证区间长度为偶数. \(1 \leq n \leq 10^5\) 基础的 fhq-treap 的题目,主要练下放标记的技巧. 首先我们需要将要求的东西转化为一个式子.例如括号序列 \((())))))(…
找平衡树练习题的时候发现了这道神题,可以说这道题是近几年单考splay的巅峰之作了. 题目大意:给出括号序列,实现区间翻转,区间反转和区间更改.查询区间最少要用几次才能改成合法序列. 分析: 首先我们单看查询操作.不妨想象一下存在着一个栈,往里面入栈和出栈,那么从原序列中取出一对(),对应着一个入和一个出.那么当)的前面再也找不到(与之对应的时候,)就要被更改成(. 这有什么用呢?我们会发现,删除一对()对答案不具有影响.接着我们删除所有可以匹配的括号,得到一个))))))((((((这样的序列…
题目描述 题解 Splay 由于有区间反转操作,因此考虑Splay. 考虑答案:缩完括号序列后剩下的一定是 $a$ 个')'+ $b$ 个'(',容易发现答案等于 $\lceil\frac a2\rceil+\lceil\frac b2\rceil$ . 怎么维护:区间合并,对于每个节点维护子树缩完括号序列后')'和'('的数目,然后pushup时考虑缩括号序列的过程,相应调整即可. 由于有Invent操作,因此还需要维护反括号序列缩完之后')'和'('的数目,并维护相应标记. 由于有Swap操…
解题思路: Replace.Swap.Invert都可以使用Splay完美解决(只需要解决一下标记冲突就好了). 最后只需要统计左右括号冲突就好了. 相当于动态统计最大前缀合和最小后缀和. 因为支持翻转反转操作,翻转标记或取反就好了. 代码: #include<cstdio> #include<cstring> #include<algorithm> #define lll tr[spc].ch[0] #define rrr tr[spc].ch[1] #define…