一、题目

点此看题

二、解法

话说老师给的课件是错的啊,把我坑了好久,我手玩样例才玩出来,最后只能去看洛谷题解了。

本题是树是用一个括号序列给出的,你要知道的是:( 代表递归下去到一个新节点,) 表示回溯到当前节点。首先这个括号序列的每一个区间都代表树上的一条路径,那么我们把能配对的括号消掉后剩下的是这种形式:)))((( ,因为能匹配的括号相当于回溯回来了,而剩下的就表示先回溯再往下走的路径。所以剩下的长度就是路径的长度,我们想要求出最长的就是直径

消去的过程好像不好算,我们可以把他转化为把原序列划分成两部分,( 看作 \(1\) ,) 看作 \(-1\),让后面的权值 \(-\) 前面的权值最大化即是路径长度。这种做法为什么能成立呢?因为 () 是不应该有贡献的,这种做法可以确保不会从 () 的中间划开,那么 () 的贡献就成为了 \(0\),那序列自然就变成了 )))((( 的形式,我们一定会从中间划开。但是作者确实不知道是怎么想到的,给括号赋值的思路值得学习。

但是这个东西可以维护?一般来说这种看似难维护但是可合并的东西我们考虑线段树,我们要维护下面几个值:

  • 区间权值和 \(sum\)
  • 区间最大的前缀和 \(lma\)
  • 区间最小的后缀和 \(rmi\)
  • 区间前缀的最佳划分答案 \(ld\)
  • 区间后缀的最佳划分答案 \(rd\)
  • 整个区间的划分答案 \(mad\)
  • 区间的某个区间划分答案(这个是真正的答案)\(mx\)

\(1-3\) 是很好维护的,我把 \(4\) 的维护方式讲一讲,剩下的就可以自己推了。分为 \(3\) 种情况:直接用左儿子的最优前缀;划分点在右儿子,用 \(ld[rs]-sum[ls]\) ;划分点在左儿子,用 \(mad[ls]+lma[rs]\)

真是毒瘤题啊,感觉思维和代码都很难的,如果 \(1-7\) 的转移不会的看看代码,结合定义理解吧!

#include <cstdio>
#include <iostream>
using namespace std;
const int M = 200005;
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,a[M];char s[M];
int sum[4*M],lma[4*M],rmi[4*M],ld[4*M],rd[4*M],mad[4*M],mx[4*M];
void up(int x)
{
int i1=x<<1,i2=x<<1|1;
sum[x]=sum[i1]+sum[i2];
lma[x]=max(lma[i1],sum[i1]+lma[i2]);
rmi[x]=min(rmi[i2],sum[i2]+rmi[i1]);
ld[x]=max(ld[i1],max(ld[i2]-sum[i1],mad[i1]+lma[i2]));
rd[x]=max(rd[i2],max(rd[i1]+sum[i2],mad[i2]-rmi[i1]));
mad[x]=max(mad[i1]+sum[i2],mad[i2]-sum[i1]);
mx[x]=max(max(mx[i1],mx[i2]),max(ld[i2]-rmi[i1],rd[i1]+lma[i2]));
}
void ins(int i,int l,int r,int id,int x)
{
if(l==r)
{
sum[i]=x;
lma[i]=max(x,0);
rmi[i]=min(x,0);
ld[i]=rd[i]=mad[i]=mx[i]=1;
return ;
}
int mid=(l+r)>>1;
if(mid>=id) ins(i<<1,l,mid,id,x);
else ins(i<<1|1,mid+1,r,id,x);
up(i);
}
signed main()
{
n=2*read()-2;m=read();
scanf("%s",s+1);
for(int i=1;i<=n;i++)
{
if(s[i]=='(') a[i]=1;
else a[i]=-1;
ins(1,1,n,i,a[i]);
}
printf("%d\n",mx[1]);
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
if(a[x]==a[y]) continue;
swap(a[x],a[y]);
ins(1,1,n,x,a[x]);
ins(1,1,n,y,a[y]);
printf("%d\n",mx[1]);
}
}

CF1149C Tree Generator™的更多相关文章

  1. Tree Generator™ CodeForces - 1149C (线段树,括号序列)

    大意: 给定括号序列, 每次询问交换两个括号, 求括号树的直径. 用[ZJOI2007]捉迷藏的方法维护即可. #include <iostream> #include <algor ...

  2. Codeforces 1149C - Tree Generator™(线段树+转化+标记维护)

    Codeforces 题目传送门 & 洛谷题目传送门 首先考虑这个所谓的"括号树"与直径的本质是什么.考虑括号树上两点 \(x,y\),我们不妨用一个"DFS&q ...

  3. Codeforces 739C - Alyona and towers(线段树)

    Codeforces 题目传送门 & 洛谷题目传送门 可能有人会问我为什么为这道 *2500 的 D1C 写题解,我觉得大概是想要在写题解数量上 dd ycx 吧,因为 ycx 到目前为止写了 ...

  4. Teach Yourself Scheme in Fixnum Days 13 Jump跳转

    Jumps One of the signal features of Scheme is its support for jumps or nonlocal control. Specificall ...

  5. THREE.JS + Blender(obj、mtl加载代码)

    2016-11-04 09:23:17 THREE.REVISION "81dev" Blender     "2.78" 1.加载OBJ.MTL文件 // T ...

  6. OS模块的常用内置方法

    chdir 修改当前工作目录到指定目录 Change the current working directory to the specified path. chmod 修改一个文件的访问权限 Ch ...

  7. codeforces选做

    收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...

  8. os.walk() 目录生成器

    目录生成器 Directory tree generator.! walk() 是 generator,直接print() 为  <generator object walk at 0x0000 ...

  9. python:OS模块

    r"""OS routines for NT or Posix depending on what system we're on. This exports: - al ...

随机推荐

  1. Nginx基础 - Nginx+Lua实现灰度发布与WAF

    1.Nginx加载Lua环境默认情况下Nginx不支持Lua模块, 需要安装LuaJIT解释器, 并且需要重新编译Nginx, 建议使用openrestry 1)环境准备 [root@localhos ...

  2. 实战交付一套dubbo微服务到k8s集群(7)之交付dubbo服务的消费者集群到K8S

    构建dubbo-demo-consumer,可以使用和dubbo-demo-service的流水线来构建 1.登录jenkins构建dubbo-demo-consumer 2.填写构建dubbo-de ...

  3. Linux网络文件下载

    wget 以网络下载 maven 包为例 wget -c http://mirrors.shu.edu.cn/apache/maven/maven-3/3.5.4/binaries/apache-ma ...

  4. Linux下的C语言编程

    一.在Linux下的C语言编程所需工具(下面所列举的都是我编程所用的工具) 1.文本编辑器 Vim 2.编译链接工具 gcc 3.调试器 gdb 4.项目管理工具 make和makefile 二.VI ...

  5. Leetcode(5)-最长回文子串(包含动态规划以及Manacher算法)

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &quo ...

  6. Petrozavodsk Winter Training Camp 2017G(栈)题解

    题意: \(M_i\)为一个\(m*m\)矩阵,已知 \[\begin{aligned} &M_0=A\\ &M_i=(\prod_{j=c_i}^{i+1}M_j)B \end{al ...

  7. we have a problem with promise

    we have a problem with promise Q: What is the difference between these four promises? doSomething() ...

  8. Vue 3 In Action

    Vue 3 In Action $ yarn add vue https://v3.vuejs.org demos refs https://v3.vuejs.org/guide/migration/ ...

  9. Gatsby Themes

    Gatsby Themes React & SSR gatsby-config.js refs https://www.gatsbyjs.com/docs/themes/ https://ww ...

  10. js currying function All In One

    js currying function All In One js 实现 (5).add(3).minus(2) 功能 例: 5 + 3 - 2,结果为 6 https://stackoverflo ...