bzoj 1095 括号序列求两点距离
大致题意: 给一棵树,每个节点最开始都是黑色,有两种操作,1.询问树中相距最远的一对黑点的距离 2.反转一个节点的颜色
一种做法:
建立出树的括号序列,类似这样: [A[B][C]],所以长度为3*n
假如我们要询问AC间的距离,提取出中间的括号:[]],匹配消去后得到],其长度就是距离.
现在我们要做的就是修改点的状态,并且动态维护答案.要用到一些求与绝对值相关的式子的技巧.
/**************************************************************
Problem: 1095
User: idy002
Language: C++
Result: Accepted
Time:2176 ms
Memory:55548 kb
****************************************************************/ #include <cstdio>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define N 100010
#define M N<<1
#define oo 0x3f3f3f3f
#define fprintf(...) struct Node {
int v[], c, e, a;
int lf, rg;
Node *ls, *rs;
void init( int type ) {
if( type== ) {
a = ;
e = false;
c = ;
for( int t=; t<; t++ ) v[t]=;
} else if( type==- ) { // (1,0)
a = -;
e = true;
c = ;
v[] = v[] = v[] = v[] = v[] = ;
v[] = v[] = -;
} else { // (0,1)
a = -;
e = true;
c = ;
v[] = v[] = v[] = v[] = v[] = ;
v[] = v[] = -;
}
}
void update() {
e = ls->e && rs->e;
v[] = ls->v[] + rs->v[];
v[] = ls->v[] + rs->v[];
v[] = max( ls->v[]+rs->v[], ls->v[]+rs->v[] );
if( !ls->e && !rs->e ) {
v[] = max( ls->v[], ls->v[]+rs->v[] );
v[] = max( ls->v[], max( ls->v[]+rs->v[], ls->v[]+rs->v[] ) );
v[] = max( rs->v[], ls->v[]+rs->v[] );
v[] = max( rs->v[], max( ls->v[]+rs->v[], ls->v[]+rs->v[] ) );
a = max( max(ls->v[]+rs->v[],ls->v[]+rs->v[]), max(ls->a,rs->a) );
} else if( !ls->e ) {
v[] = ls->v[];
v[] = ls->v[];
v[] = ls->v[]+rs->v[];
v[] = max( ls->v[]+rs->v[], ls->v[]+rs->v[] );
a = ls->a;
} else if( !rs->e ) {
v[] = ls->v[]+rs->v[];
v[] = max( ls->v[]+rs->v[], ls->v[]+rs->v[] );
v[] = rs->v[];
v[] = rs->v[];
a = rs->a;
} else {
a = -;
}
}
void reverse( int pos ) {
if( lf==rg ) {
if( c ) {
c = ;
a = -;
e = true;
} else {
c = ;
a = ;
e = false;
}
return;
}
int mid=(lf+rg)>>;
if( pos<=mid ) ls->reverse(pos);
else rs->reverse(pos);
update();
}
}pool[N**], *tail=pool, *root; int n, m;
int head[N], dest[M], next[M], etot;
int dfn[N], sgn[N*], fat[N], idc; void adde( int u, int v ) {
etot++;
next[etot] = head[u];
dest[etot] = v;
head[u] = etot;
}
void dfs( int u ) {
sgn[++idc] = ;
dfn[u] = ++idc;
fprintf( stderr, "[" );
fprintf( stderr, "%d", u );
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==fat[u] ) continue;
fat[v] = u;
dfs(v);
}
sgn[++idc] = -;
fprintf( stderr, "]" );
}
Node *build( int lf, int rg ) {
Node *nd = ++tail;
nd->lf=lf, nd->rg=rg;
if( lf==rg ) {
nd->init( sgn[lf] );
} else {
int mid=(lf+rg)>>;
nd->ls = build( lf, mid );
nd->rs = build( mid+, rg );
nd->update();
}
fprintf( stderr, "[%d,%d] a=%2d e=%d v[0~6] = %2d %2d %2d %2d %2d %2d %2d\n",
lf, rg, nd->a, nd->e, nd->v[], nd->v[],
nd->v[], nd->v[], nd->v[], nd->v[], nd->v[] );
return nd;
}
int main() {
scanf( "%d", &n );
for( int i=,u,v; i<n; i++ ) {
scanf( "%d%d", &u, &v );
adde( u, v );
adde( v, u );
}
for( int i=; i<=n+n+n; i++ )
fprintf( stderr, "%d", i% );
fprintf( stderr, "\n" );
fat[] = ;
dfs();
fprintf( stderr, "\n" );
root = build( , idc );
scanf( "%d", &m );
for( int i=,u; i<=m; i++ ) {
char ch[];
scanf( "%s\n", ch );
if( ch[]=='G' ) {
printf( "%d\n", root->a );
} else {
scanf( "%d", &u );
root->reverse(dfn[u]);
}
}
}
另一种做法大概是用点分,然后用堆维护最值.
bzoj 1095 括号序列求两点距离的更多相关文章
- [BZOJ 4350]括号序列再战猪猪侠 题解(区间DP)
[BZOJ 4350]括号序列再战猪猪侠 Description 括号序列与猪猪侠又大战了起来. 众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号 序列S合法,当且仅当: 1.( )是一个 ...
- bzoj 4244 括号序列dp
将各种情况绕环等看作括号序列,括号内的区域上下都需要累加答案,左右也是 f[i][j] 代表 前i个车站已经处理完的有j个左括号的最小权值 我们可以发现,更新的来源来自于 i-1, 和 i 将上 描述 ...
- bzoj 2209 括号序列
反转操作 + 翻转操作 = 对称操作 因为上面三个操作都是自己的逆操作,所以我们只需要实现对称操作和反转操作,就可以搞定翻转操作. #include <cstdio> #include & ...
- BZOJ 1095 捉迷藏(线段树维护括号序列)
对于树的一个括号序列,树上两点的距离就是在括号序列中两点之间的括号匹配完之后的括号数... 由此可以得出线段树的做法.. #include<cstdio> #include<iost ...
- hdu 6299 Balanced Sequence (括号序列,贪心)
大意: 记$f(t)$表示字符串$t$的最长括号匹配子序列, 给定n个括号序列, 求它们重排后的最大f(t). 首先可以注意到一个括号序列中已经匹配的可以直接消去, 一定不会影响最优解. 那么这样最终 ...
- NX二次开发-UFUN计算两点距离UF_VEC3_distance
NX11+VS2013 #include <uf.h> #include <uf_curve.h> #include <uf_vec.h> UF_initializ ...
- 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树
[题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...
- bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...
- BZOJ.1095.[ZJOI2007]捉迷藏(线段树 括号序列)
BZOJ 洛谷 对树DFS得到括号序列.比如这样一个括号序列:[A[B[E][F[H][I]]][C][D[G]]]. 那比如\(D,E\)间的最短距离,就是将\(D,E\)间的括号序列取出:][[] ...
随机推荐
- springboot系列十五、springboot集成PageHelper
一.介绍 项目中经常会遇到分页,PageHelper为我们解决了这个问题.本质上实现了Mybatis的拦截器,作了分页处理. 二.配置PageHelper 1.引入依赖 pagehelper-spri ...
- Python单元测试unittest - 单元测试框架
一.unittest简介 unitest单元测试框架最初是有JUnit的启发,它支持测试自动化,共享测试的设置和关闭代码,将测试聚合到集合中,以及测试与报告框架的独立性. 二.unittest相关概念 ...
- 016_nginx运维问题总结
一.关于nginx请求包过大的解决思路 message-api.jyall.me.conf nginx报错问题问题定位,经分析跟接入navigator后关联不大,可参考一下结论连接超时抓包分析了一下每 ...
- echarts地图使用
在使用echarts3当中,地图需要的数据时分开的,需要自己下载,而在echarts3官网上的地图数据只有全国.中国.各省的地图 如果我们需要使用更详细的地图,需要在echarts2的生成需要的地级市 ...
- PYTHON-函数的定义与调用,返回值,和参数
函数基础'''1. 什么是函数 具备某一功能的工具->函数 事先准备工具的过程--->函数的定义 遇到应用场景,拿来就用---->函数的调用 函数分类两大类: 1. 内置函数 2. ...
- OCM_第十二天课程:Section6 —》数据库性能调优_ 资源管理器/执行计划
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- OCM_第九天课程:Section4—》OCM课程环境搭建
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- poj2299树状数组入门,求逆序对
今天入门了树状数组 习题链接 https://blog.csdn.net/liuqiyao_01/article/details/26963913 离散化数据:用一个数组来记录每个值在数列中的排名,不 ...
- oracle中游标详细用法
转自:http://blog.csdn.net/liyong199012/article/details/8948952 游标的概念: 游标是SQL的一个内存工作区,由系统或用户以变量的形式定 ...
- find算法
find(beg, end, val) :根据equal操作符,循序查找[first, last)内所有的元素,找出第一个匹配“等同条件者”.如果找到,就返回一个指向钙元素的迭代器,否者返回迭代器 ...