BZOJ

洛谷


对树DFS得到括号序列。比如这样一个括号序列:[A[B[E][F[H][I]]][C][D[G]]]

那比如\(D,E\)间的最短距离,就是将\(D,E\)间的括号序列取出:][[][]]][][,然后去掉其中匹配的括号,得到:]][[

所以\(D,E\)在树上的最短距离为\(4\)。因为左边一个右括号就表示向上一层,右边一个左括号就表示向下一层。

对一个区间记一个二元组\((a,b)\),表示该区间(去掉匹配括号后的)括号序列是]]..][..[,一共\(a\)个],\(b\)个[

那这个区间左右端点的距离就是\(a+b\),我们要维护最大的\(a+b\)(假设是求两黑点间的最大距离,那这个区间的左右端点都是黑点才能更新答案)。

记左右区间的状态分别是\((a_1,b_1),(a_2,b_2)\)。

那两个区间合并后的状态是:

\(b_1\leq a_2\)时,\(=(a_1+a_2-b_1,\ b_2)\)

\(b_1>a_2\)时,\(=(a_1,\ b_2+b_1-a_2)\)

\(a+b\)的值其实就是\(a_1+b_2+|a_2-b_1|=a_1+b_2+\max(a_2-b_1,\ b_1-a_2)=\max(a_1-b_1+(a_2+b_2),\ a_1+b_1+(b_2-a_2))\)。

也就是这个区间的答案有两种更新方式:左区间的\(\max\{a-b\}+\)右区间的\(\max\{a+b\}\),或是,左区间的\(\max\{a+b\}+\)右区间的\(\max\{b-a\}\)。

所以我们对每个区间维护\(a,b,\max\{a-b\},\max\{b-a\},\max\{a+b\}\)。

(注意更新答案是要求两端点都是黑点,所以能更新\(\max\{a-b\}\)的要包含区间右端点且区间左端点必须是黑点,同理更新\(\max\{b-a\}\)的要包含区间左端点且区间右端点必须是黑点,而\(\max\{a+b\}\)我们要根据区间左右端点是否必须为黑点维护两个值。)

而两区间合并后的\(a-b\),无论\(b_1,a_2\)的大小关系,都是\(a_1-b_1+a_2-b_2\);\(b-a\)就是\(b_1-a_2+b_2-a_2\)。也就是两区间的这两个信息可以直接相加合并。

(如\(max\{a-b\}\),可以由右区间的\(\max\{a-b\}\)得到,或是\(\max\{a_1-b_1\}+a_2-b_2\)得到,右区间的\(a_2,b_2\)是必选的)

记\(\max\{a-b\}\)为\(vab\),\(\max\{b-a\}\)为\(vba\)。

对于包含区间左端点且区间右端点为黑点的\(\max\{a+b\}\)(记作\(vr\)好了,对应的就记作\(vl\)),合并左右子区间的时候,要么是从左儿子的\(vr_l\)直接转移,要么是用左儿子的和+右儿子的一些和转移。

而合并得到\(a+b\)的时候是这样的:\(\max(a_1-b_1+(a_2+b_2),\ a_1+b_1+(b_2-a_2))\),也就是要么是左区间的\(a-b+\)右区间的\(\max\{a+b\}\),即\(a_l-b_l+vr_r\),要么是左区间的\(a-b+\)右区间的\(\max\{b-a\}\),即\(a_l+b_l+vba_r\)。

\(vr\)同理。

那状态\(a,b\)以及这\(4\)个\(\max\)都能合并了,维护一下就好咯。(具体见代码吧,挺好理解的)

复杂度\(O(n\log n)\)。

注意建树的时候就是建出[A[B[E][F[H][I]]][C][D[G]]]这样的长度\(3n\)的序列,\(A,B,...\)代表的是点的编号。修改的时候改对应字母位置即可。(因为就算去掉字母,括号是一定的,而且查的时候也只是查两字母之间的括号数)

对端点必须为黑点的要求,如果某点是白点或是括号,将各值设成\(-INF\)即可。

还是感觉这个建树好迷啊...


至于Qtree4那题,边权不为\(1\),怎么用括号序列做啊...

看到有树剖+堆就是链分治的,还有写Toptree的=-=,都跑的挺快。不管了弃疗了。

动态点分治做法:https://www.cnblogs.com/SovietPower/p/8618930.html。


//39460kb	3068ms
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5,M=N*3,INF=1<<29; int A[M],Enum,H[N],nxt[N<<1],to[N<<1],pos[N],col[N];//0:close 1:open
char IN[MAXIN],*SS=IN,*TT=IN;
struct Segment_Tree
{
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define S M<<2
int ans[S],a[S],b[S],vab[S],vba[S],vl[S],vr[S];//vab:max{a-b} vba:max{b-a} vl:max{a+b}且左端点为黑点
#undef S
inline void Init(int p,int rt)
{
a[rt]=A[p]==-2, b[rt]=A[p]==-1, ans[rt]=-INF;//a是右括号 b是左括号。。
if(A[p]<0 || col[A[p]]) vab[rt]=vba[rt]=vl[rt]=vr[rt]=-INF;
else vab[rt]=vba[rt]=vl[rt]=vr[rt]=0;
}
inline void Update(int rt)
{
int l=ls,r=rs;
a[rt]=a[l]+std::max(0,a[r]-b[l]), b[rt]=b[r]+std::max(0,b[l]-a[r]);
ans[rt]=std::max(std::max(ans[l],ans[r]),std::max(vab[l]+vr[r],vl[l]+vba[r]));
vab[rt]=std::max(vab[r],a[r]-b[r]+vab[l]);
vba[rt]=std::max(vba[l],b[l]-a[l]+vba[r]);
vl[rt] =std::max(vl[r],std::max(vab[l]+a[r]+b[r],vl[l]+b[r]-a[r]));
vr[rt] =std::max(vr[l],std::max(a[l]-b[l]+vr[r],a[l]+b[l]+vba[r]));
}
void Build(int l,int r,int rt)
{
if(l==r) {Init(l,rt); return;}
int m=l+r>>1;
Build(lson), Build(rson), Update(rt);
}
void Modify(int l,int r,int rt,int p)
{
if(l==r) {Init(l,rt); return;}
int m=l+r>>1;
p<=m ? Modify(lson,p) : Modify(rson,p);
Update(rt);
}
}T; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline void AE(int u,int v)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
inline char GetOpt()
{
register char c=gc();
while(c!='C'&&c!='G') c=gc();
return c;
}
void DFS(int x)
{
static int Index=0;
A[++Index]=-1, A[pos[x]=++Index]=x;
for(int i=H[x]; i; i=nxt[i]) if(!pos[to[i]]) DFS(to[i]);
A[++Index]=-2;
} int main()
{
#define S 1,cnt,1
const int n=read(),cnt=n*3;
for(int i=1; i<n; ++i) AE(read(),read());
DFS(1), T.Build(S);
for(int Q=read(),tot=n,x; Q--; )
switch(GetOpt())
{
case 'C': col[x=read()]^=1, tot+=col[x]?-1:1, T.Modify(S,pos[x]); break;
case 'G': tot>1?printf("%d\n",T.ans[1]):tot==1?puts("0"):puts("-1"); break;
}
return 0;
}

BZOJ.1095.[ZJOI2007]捉迷藏(线段树 括号序列)的更多相关文章

  1. [ZJOI2007]捉迷藏 (线段树,括号序列)

    大意: 给定树, 要求维护一个点集, 支持删点添点, 询问点集直径. 本题做法比较多. 一个显然的做法是, 线段树维护区间直径, 然后根据点集直径的性质, 合并后直径端点一定是四个端点其中两个, 枚举 ...

  2. [bzoj1095][ZJOI2007]Hide 捉迷藏——线段树+括号序列

    题目大意 给定一棵所有点初始值为黑的无权树,你需要支援两种操作: 把一个点的颜色反转 统计最远黑色点对. 题解 本题是一个树上的结构.对于树上的结构,我们可以采用点分治.树链剖分等方法处理,这个题用了 ...

  3. [BZOJ 1095] [ZJOI2007]Hide 捉迷藏——线段树+括号序列(强..)

    神做法-%dalao,写的超详细 konjac的博客. 如果觉得上面链接的代码不够优秀好看,欢迎回来看本蒟蒻代码- CODE WITH ANNOTATION 代码中−6-6−6表示左括号'[',用−9 ...

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

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

  5. 洛谷.4115.Qtree4/BZOJ.1095.[ZJOI2007]Hide捉迷藏(动态点分治 Heap)

    题目链接 洛谷 SPOJ BZOJ1095(简化版) 将每次Solve的重心root连起来,会形成一个深度为logn的树,就叫它点分树吧.. 我们对每个root维护两个东西: 它管辖的子树中所有白点到 ...

  6. Bzoj 2752 高速公路 (期望,线段树)

    Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...

  7. bzoj 1095 [ZJOI2007]Hide 捉迷藏(括号序列+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1095 [题意] 给定一棵树,树上颜色或白或黑而且可以更改,多个询问求最远黑点之间的距离 ...

  8. BZOJ 1095: [ZJOI2007]Hide 捉迷藏(线段树维护括号序列)

    这个嘛= =链剖貌似可行,不过好像代码长度很长,懒得打(其实是自己太弱了QAQ)百度了一下才知道有一种高大上的叫括号序列的东西= = 岛娘真是太厉害了,先丢链接:http://www.shuizilo ...

  9. BZOJ 1095 捉迷藏(线段树维护括号序列)

    对于树的一个括号序列,树上两点的距离就是在括号序列中两点之间的括号匹配完之后的括号数... 由此可以得出线段树的做法.. #include<cstdio> #include<iost ...

随机推荐

  1. Visual Studio UML

    1 .类图设计 2.动态图设计,业务工作流程说明了业务为所想服务的业务助教提供了所需要的价值而必须完成的工作,业务用例由一系列的活动组成,它们共同为业务主角生成某些工件,工作流程通常包括一个基本的工作 ...

  2. Decimal integer conversion

    问题 : Decimal integer conversion 时间限制: 1 Sec  内存限制: 128 MB 题目描述 XiaoMing likes mathematics, and he is ...

  3. C++ Primer 笔记——语句

    switch 内部的变量定义 1.因为C++语言规定,不允许跨过变量的初始化语句直接跳转到该变量作用域内的另一位置,所以有了如下情况: bool bsuccess = false; switch (b ...

  4. java读取pdf和MS Office文档

    有时候PDF中的文字无法复制,这可能是因为PDF文件加密了,不过使用PDFBox开源软件就可以把它读出来. 还有一个用于创建PDF文件的项目----iText. PDFBox下面有两个子项目:Font ...

  5. 没有系列化导致错误:java.io.NotSerializableException: com.bjpowernode.bean.Team

    java.io.NotSerializableException: com.bjpowernode.bean.Team Cause: java.io.NotSerializableException: ...

  6. The.Glory.of.Innovation 创新之路2科学基石

    犹太民族很早就确立了他们的生存法则:资源.土地,以及一切有形的东西都会消失,一个人最重要的财富是自己的头脑.是知识.是创造.   有些选择是被动的,有些选择是主动的,一旦决心要把技术变成自己的,独立的 ...

  7. base | Thread类、ThreadData结构体 、CurrentThread命名空间

    __thread __thread是GCC内置的线程局部存储设施,存取效率可以和全局变量相比.__thread变量每一个线程有一份独立实体,各个线程的值互不干扰.可以用来修饰那些带有全局性且值可能变, ...

  8. HDFS的一些配置文件修改

    sbin/start-dfs.sh 和 sbin/stop-dfs.sh 在第二行增加如下内容 HDFS_DATANODE_USER=root HDFS_DATANODE_SECURE_USER=hd ...

  9. javaScript事件(八)事件类型之变动事件

    DOM2级的变动(mutation)事件能在DOM中某一部分发送变化时给出提示.变动事件为XML或HTML DOM设计的,并不特定于某种语言.DOM2级定义了如下变动事件. DOMSubtreeMod ...

  10. BZOJ2178 圆的面积并 计算几何 辛普森积分

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2178.html 题目传送门 - BZOJ2178 题意 给出 $n(n\leq 1000)$ 个圆,求 ...