CF1149C Tree Generator™
一、题目
二、解法
话说老师给的课件是错的啊,把我坑了好久,我手玩样例才玩出来,最后只能去看洛谷题解了。
本题是树是用一个括号序列给出的,你要知道的是:( 代表递归下去到一个新节点,) 表示回溯到当前节点。首先这个括号序列的每一个区间都代表树上的一条路径,那么我们把能配对的括号消掉后剩下的是这种形式:)))((( ,因为能匹配的括号相当于回溯回来了,而剩下的就表示先回溯再往下走的路径。所以剩下的长度就是路径的长度,我们想要求出最长的就是直径 。
消去的过程好像不好算,我们可以把他转化为把原序列划分成两部分,( 看作 \(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™的更多相关文章
- Tree Generator™ CodeForces - 1149C (线段树,括号序列)
大意: 给定括号序列, 每次询问交换两个括号, 求括号树的直径. 用[ZJOI2007]捉迷藏的方法维护即可. #include <iostream> #include <algor ...
- Codeforces 1149C - Tree Generator™(线段树+转化+标记维护)
Codeforces 题目传送门 & 洛谷题目传送门 首先考虑这个所谓的"括号树"与直径的本质是什么.考虑括号树上两点 \(x,y\),我们不妨用一个"DFS&q ...
- Codeforces 739C - Alyona and towers(线段树)
Codeforces 题目传送门 & 洛谷题目传送门 可能有人会问我为什么为这道 *2500 的 D1C 写题解,我觉得大概是想要在写题解数量上 dd ycx 吧,因为 ycx 到目前为止写了 ...
- 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 ...
- THREE.JS + Blender(obj、mtl加载代码)
2016-11-04 09:23:17 THREE.REVISION "81dev" Blender "2.78" 1.加载OBJ.MTL文件 // T ...
- OS模块的常用内置方法
chdir 修改当前工作目录到指定目录 Change the current working directory to the specified path. chmod 修改一个文件的访问权限 Ch ...
- codeforces选做
收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...
- os.walk() 目录生成器
目录生成器 Directory tree generator.! walk() 是 generator,直接print() 为 <generator object walk at 0x0000 ...
- python:OS模块
r"""OS routines for NT or Posix depending on what system we're on. This exports: - al ...
随机推荐
- Ansible 自动化部署
参考 BLOG: Ansible 系列模块 Ansible 部署与使用 Ansible Book Ansible Ansible 是一个自动化统一配置管理工具,自动化主要体现在 Ansible 集成了 ...
- Redis 的缓存淘汰机制(Eviction)
本文从源码层面分析了 redis 的缓存淘汰机制,并在文章末尾描述使用 Java 实现的思路,以供参考. 相关配置 为了适配用作缓存的场景,redis 支持缓存淘汰(eviction)并提供相应的了配 ...
- Socket 编程简介
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. 本章节我们为大家接收 Perl ...
- spring-cloud-netflix-eureka-server
一.构建springcloud父pom工程,管理版本 pom.xml <?xml version="1.0" encoding="UTF-8"?> ...
- Spring应用上下文生命周期
Spring应用上下文生命周期整体分成四个阶段 ConfigurableApplicationContext#refresh,加载或者刷新持久化配置 ConfigurableApplicationCo ...
- CSS3实现 垂直居中 水平居中 的技巧
1 1 1 How To Center Anything With CSS Front End posted by Code My Views 1 Recently, we took a dive i ...
- 前端 vs 后端
前端 vs 后端 前端与后端: 有什么区别? 前端和后端是计算机行业中最常用的两个术语. 在某种程度上,它们成了流行语. 它们决定了您作为软件开发人员所从事的工作类型,所使用的技术以及所获得的收入. ...
- vue & template & v-else & v-for bug
vue & template & v-else & v-for bug nested table bug https://codepen.io/xgqfrms/pen/wvaG ...
- Nestjs 验证对象数组
route @Patch(':id') patch(@Param('id') id: string, @Body() removeEssayDto: RemoveEssayDto) { return ...
- django学习-27.admin管理后台里:对列表展示页面的数据展示进行相关优化
目录结构 1.前言 2.完整的操作步骤 2.1.第一步:查看ModelAdmin类和BaseModelAdmin类的源码 2.2.第二步:查看表animal对应的列表展示页面默认的数据展示 2.3.第 ...