一、题目

点此看题

二、解法

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

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

消去的过程好像不好算,我们可以把他转化为把原序列划分成两部分,( 看作 \(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. Python_小程序

    一.开发前的准备工作 1.申请AppID:一个账号对应一个小程序,个人/个体只能申请5个小程序 2.下载开发工具 二.小程序的文件结构 三. 1.数据绑定 1.1数据的设置 Page( data:{ ...

  2. OpenStack-知识点补充

    登录计算节点查看进程 [root@compute ~]# ps aux | grep kvm root 824 0.0 0.0 0 0 ? S< 10:19 0:00 [kvm-irqfd-cl ...

  3. 数据库之ODPS中sql语句指南

    此篇博文为本人在实际工作中应用总结,转载请注明出处. 持续更新中 一.增 1.增加一列(向csp_hsy_count_info表中增加sale_qty列) ALTER TABLE csp_hsy_co ...

  4. redis跳表

    redis使用跳表作为有序集合的底层实现之一,下面来看下跳表的结构 一.跳表的结构

  5. HDU 4866 Shooting(主席树)题解

    题意:在一个射击游戏里面,游戏者可以选择地面上[1,X]的一个点射击,并且可以在这个点垂直向上射击最近的K个目标,每个目标有一个价值,价值等于它到地面的距离.游戏中有N个目标,每个目标从L覆盖到R,距 ...

  6. free open movie API all in one

    free open movie API all in one movie API TMDb API The Movie Database https://www.themoviedb.org/docu ...

  7. Swift 5.3

    Swift 5.3 https://swift.org/blog/ refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  8. js GC & stack heap

    js GC & stack heap stack 栈,函数执行形成执行栈帧,变量名,指针 heap 堆,非结构化的数据(Object),分配的内存的存储空间 js 垃圾回收机制 https:/ ...

  9. C++算法代码——标题统计

    题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=2327 题目描述 凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意: ...

  10. JUC学习

    JUC是java.util.concurrent包 并发编程的工具包 并发.并行 并发:多线程操作一个资源 并行:多人一起走 并发编程的本质:充分利用cpu的资源 线程的几个状态 新建 运行 堵塞 等 ...