要点

  • 括号序列平衡度即树深度的性质
  • 相当于中序遍历,则两点间最浅的地方即是LCA的性质
  • 线段树维护\(d(a) + d(c) - 2*d(lca(a,c))\),一层层剥,思考维护这个量需要什么,结果维护一大堆。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = 2e5 + 5; int n, q;
char s[maxn]; class SegmentTree {
public:
#define ls (p << 1)
#define rs (p << 1 | 1) struct node {
int l, r;
int depth;//its root is s[l]
int ans;//d(a) + d(c) - 2d(lca(a, c))
int lmax;//d(a) - 2d(lca(a, c))
int rmax;//d(c) - 2d(lca(a, c))
int mxd;//max depth
int mnd;//min depth void init(int val) {
mxd = mnd = depth = val;
lmax = rmax = -val;
ans = 0;
}
}t[maxn * 3]; void Push_up(int p) {
// b = lca(a, c), a <= b <= c
t[p].depth = t[ls].depth + t[rs].depth;
t[p].mxd = max(t[ls].mxd, t[rs].mxd + t[ls].depth);
t[p].mnd = min(t[ls].mnd, t[rs].mnd + t[ls].depth);
t[p].lmax = max(t[ls].lmax, t[rs].lmax - t[ls].depth);//a, b both in l or r
t[p].lmax = max(t[p].lmax, t[ls].mxd - 2 * (t[rs].mnd + t[ls].depth));//a in l and b in r
t[p].rmax = max(t[ls].rmax, t[rs].rmax - t[ls].depth);//b, c both in l or r
t[p].rmax = max(t[p].rmax, t[rs].mxd + t[ls].depth - 2 * t[ls].mnd);//b int l and c in r
t[p].ans = max(t[ls].ans, t[rs].ans);//a,b,c all in l or r
t[p].ans = max(t[p].ans, max(t[ls].lmax + t[rs].mxd + t[ls].depth, t[ls].mxd + t[rs].rmax - t[ls].depth));//ab in l, c in r || a in l, bc in r
} void Build(int l, int r, int p) {
t[p].l = l, t[p].r = r;
if (l == r) {
t[p].init(s[l] == '(' ? 1 : -1);
return;
}
int mid = (l + r) >> 1;
Build(l, mid, ls);
Build(mid + 1, r, rs);
Push_up(p);
} void Modify(int l, int r, int p) {
if (t[p].l == t[p].r) {
t[p].init(s[l] == '(' ? 1 : -1);
return;
}
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) Modify(l, r, ls);
if (mid < r) Modify(l, r, rs);
Push_up(p);
}
}tree; int main() {
scanf("%d %d", &n, &q);
scanf("%s", s + 1); n = (n - 1) << 1;
tree.Build(1, n, 1);
printf("%d\n", tree.t[1].ans); for (int a, b; q; q--) {
scanf("%d %d", &a, &b);
if (s[a] != s[b]) {
swap(s[a], s[b]);
tree.Modify(a, a, 1);
tree.Modify(b, b, 1);
}
printf("%d\n", tree.t[1].ans);
}
}

最新文章

  1. windows下 安装 rabbitMQ 及操作常用命令
  2. H5图片裁剪升级版
  3. Linux 用户添加sudo 权限
  4. oracleclient连oracle库 报System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本
  5. vue-cli + webpack 多页面实例应用
  6. memcached 介绍
  7. java 检查抛出的异常是否是要捕获的检查性异常或运行时异常或错误
  8. shell每日发邮件
  9. iOS学习之根据文本内容动态计算文本框高度的步骤
  10. HttpWebRequest和WebClient的区别
  11. Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)(转)
  12. hdu1069(dp)
  13. C#图解教程 第十七章 泛型
  14. solr索引报错(java.lang.OutOfMemoryError:GC overhead limit exceeded)
  15. Perl一行式:文本编解码、替换
  16. Sql Server2014数据库清理日志
  17. 新世界主机_XenServer7.0都有哪些优势?
  18. utf-8的中文,一个字符占几个字节
  19. [翻译] ZLSwipeableView
  20. CodeForces 540D Bad Luck Island (DP)

热门文章

  1. Sql Server 中查询存储过程的修改时间
  2. How to ping and test for a specific port from Linux or Unix command line
  3. PKUWC 2018 真实排名
  4. CodeForces - 752B
  5. /proc/cpuinfo和/proc/meminfo来查看cpu信息与内存信息
  6. odoo:Actions
  7. C++与Matlab混合编程之:矩阵数据结构
  8. git add命令后出现Another git process seems to be running in this repositor...错误提示
  9. windows下 将tomcat做成服务,并于oracle后启动
  10. PHP的垃圾回收机制(开启垃圾回收机制后的优缺点是什么)