要点

  • 括号序列平衡度即树深度的性质
  • 相当于中序遍历,则两点间最浅的地方即是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);
}
}

Codeforces 1150E(树、线段树)的更多相关文章

  1. 浅谈树套树(线段树套平衡树)&学习笔记

    0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...

  2. Vasya and a Tree CodeForces - 1076E(线段树+dfs)

    I - Vasya and a Tree CodeForces - 1076E 其实参考完别人的思路,写完程序交上去,还是没理解啥意思..昨晚再仔细想了想.终于弄明白了(有可能不对 题意是有一棵树n个 ...

  3. Codeforces 787D. Legacy 线段树建模+最短路

    D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  4. Almost Regular Bracket Sequence CodeForces - 1095E (线段树,单点更新,区间查询维护括号序列)

    Almost Regular Bracket Sequence CodeForces - 1095E You are given a bracket sequence ss consisting of ...

  5. Sereja and Brackets CodeForces - 380C (线段树+分治思路)

    Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...

  6. CodeForces 91B Queue (线段树,区间最值)

    http://codeforces.com/problemset/problem/91/B B. Queue time limit per test: 2 seconds memory limit p ...

  7. Codeforces 343D WaterTree - 线段树, DFS序

    Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...

  8. codeforces 787D - Legacy 线段树优化建图,最短路

    题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...

  9. Subtree Minimum Query CodeForces - 893F (线段树合并+线段树动态开点)

    题目链接:https://cn.vjudge.net/problem/CodeForces-893F 题目大意:给你n个点,每一个点有权值,然后这n个点会构成一棵树,边权为1.然后有q次询问,每一次询 ...

  10. Codeforces 765F Souvenirs 线段树 + 主席树 (看题解)

    Souvenirs 我们将询问离线, 我们从左往右加元素, 如果当前的位置为 i ,用一棵线段树保存区间[x, i]的答案, 每次更新完, 遍历R位于 i 的询问更新答案. 我们先考虑最暴力的做法, ...

随机推荐

  1. VS2010-MFC(对话框:为对话框添加控件)

    转自:http://www.jizhuomi.com/software/151.html 上一讲创建了一个名为“Addition”的工程,目的是生成一个实现加法运算的应用程序.实现加法计算有几个必要的 ...

  2. Android基础控件ToggleButton和Switch开关按钮

    1.简介 ToggleButton和Switch都是开关按钮,只不过Switch要Android4.0之后才能使用! ToggleButton <!--checked 是否选择--> &l ...

  3. C++ 函数模板&类模板详解

    在 C++ 中,模板分为函数模板和类模板两种.函数模板是用于生成函数的,类模板则是用于生成类的. 函数模板&模板函数     类模板&模板类  必须区分概念 函数模板是模板,模板函数时 ...

  4. JS基础语法之DOM02(事件)

    1.常用事件 1.onclick 单击 应用场景:为按钮绑定 2.ondbclick 双击 3.onfocus   获得焦点 4.onblur 失去焦点 应用场景:用于表单验证,用户离开某个输入框时, ...

  5. vue表格之:formatter=fun

    作用:对从数据库中取出的数据进行处理后展示. 示例1: partner1为从数据库中查询出的展示字段,值为数字id,需要转化成中文名称 partners为全量查询结果,包含了id与中文名称的一一对应关 ...

  6. Linux常用命令的缩写含义

    命令缩写: ls:list(列出目录内容) cd:Change Directory(改变目录) su:switch user 切换用户rpm:redhat package manager 红帽子打包管 ...

  7. JS如何获取地址栏url后面的参数?

    本文不再更新,可能存在内容过时的情况,实时更新请移步我的新博客:JS如何获取地址栏url后面的参数?: 这里提供了两种获取地址栏url后面参数的方法: 方式1 传参: window.location. ...

  8. js实现事件委托

    事件委托的概念: 事件委托就是利用事件冒泡,把事件加到父元素或祖先元素上,触发执行效果. 事件委托的写法: btn6.onclick = function(event){ event = event ...

  9. HZOI20190902模拟35题解

    题面: A:公园 DAG上想拓扑dp 然而博主记忆化搜索了一下 设f[i][j]表示从i节点走j个点出公园所用的最小时间 则$f[u][i]=min(f[v][j-1]+dis_{u,v})$; 然后 ...

  10. BZOJ 3236 AHOI 2013 作业 莫队+树状数组

    BZOJ 3236 AHOI 2013 作业 内存限制:512 MiB 时间限制:10000 ms 标准输入输出     题目类型:传统 评测方式:文本比较 题目大意: 此时己是凌晨两点,刚刚做了Co ...