http://www.lydsy.com/JudgeOnline/problem.php?id=2325

设线段树节点区间为[l,r]

每个节点维护sum[0/1][0/1]  从l的A/B区域到r的A/B区域 经过冰块的最大数量

mx[0][0] 从l的A区域出发向r经过冰块的最大数量

mx[0][1] 从l的B区域出发向r经过冰块的最大数量

mx[1][0] 从r的A区域出发向l经过冰块的最大数量

mx[1][1] 从r的B区域出发向l经过冰块的最大数量

#include<cstdio>
#include<iostream>
#include<algorithm> #define N 30001 using namespace std; int n; int front[N],nxt[N<<],to[N<<],tot; int fa[N],dep[N],siz[N];
int bl[N]; int id[N],dy[N],cnt; bool a[N][]; #define max(x,y) ((x)>(y) ? (x) : (y)) struct node
{
int sum[][];
int mx[][]; node()
{
for(int i=;i<;++i)
for(int j=;j<;++j)
sum[i][j]=mx[i][j]=;
} node operator + (node p) const
{
node k;
for(int i=;i<=;++i)
for(int j=;j<=;++j)
{
if(sum[i][] && p.sum[][j])
k.sum[i][j]=max(k.sum[i][j],sum[i][]+p.sum[][j]);
if(sum[i][] && p.sum[][j])
k.sum[i][j]=max(k.sum[i][j],sum[i][]+p.sum[][j]);
}
k.mx[][]=max(k.sum[][],k.sum[][]);
k.mx[][]=max(k.sum[][],k.sum[][]);
k.mx[][]=max(k.sum[][],k.sum[][]);
k.mx[][]=max(k.sum[][],k.sum[][]);
if(sum[][]) k.mx[][]=max(k.mx[][],sum[][]+p.mx[][]);
if(sum[][]) k.mx[][]=max(k.mx[][],sum[][]+p.mx[][]);
if(sum[][]) k.mx[][]=max(k.mx[][],sum[][]+p.mx[][]);
if(sum[][]) k.mx[][]=max(k.mx[][],sum[][]+p.mx[][]);
if(p.sum[][]) k.mx[][]=max(k.mx[][],mx[][]+p.sum[][]);
if(p.sum[][]) k.mx[][]=max(k.mx[][],mx[][]+p.sum[][]);
if(p.sum[][]) k.mx[][]=max(k.mx[][],mx[][]+p.sum[][]);
if(p.sum[][]) k.mx[][]=max(k.mx[][],mx[][]+p.sum[][]);
k.mx[][]=max(k.mx[][],mx[][]);
k.mx[][]=max(k.mx[][],mx[][]);
k.mx[][]=max(k.mx[][],p.mx[][]);
k.mx[][]=max(k.mx[][],p.mx[][]);
return k;
} void turn()
{
swap(sum[][],sum[][]);
swap(mx[][],mx[][]);
swap(mx[][],mx[][]);
} }tr[N<<]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} void dfs1(int x)
{
siz[x]=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x])
{
fa[to[i]]=x;
dep[to[i]]=dep[x]+;
dfs1(to[i]);
siz[x]+=siz[to[i]];
}
} void dfs2(int x,int top)
{
bl[x]=top;
id[x]=++cnt;
dy[cnt]=x;
int y=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x] && siz[to[i]]>siz[y]) y=to[i];
if(y) dfs2(y,top);
else return;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=y && to[i]!=fa[x]) dfs2(to[i],to[i]);
} void build(int k,int l,int r)
{
if(l==r)
{
if(a[dy[l]][]) tr[k].sum[][]=;
if(a[dy[l]][]) tr[k].sum[][]=;
if(a[dy[l]][] && a[dy[l]][]) tr[k].sum[][]=tr[k].sum[][]=;
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
return;
}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
tr[k]=tr[k<<]+tr[k<<|];
} node query(int k,int l,int r,int opl,int opr)
{
if(l>=opl && r<=opr) return tr[k];
int mid=l+r>>;
if(opr<=mid) return query(k<<,l,mid,opl,opr);
else if(opl>mid) return query(k<<|,mid+,r,opl,opr);
else return query(k<<,l,mid,opl,opr)+query(k<<|,mid+,r,opl,opr);
} void Query(int u,int v)
{
node ansu,ansv;
bool firstu=false,firstv=false;
while(bl[u]!=bl[v])
{
if(dep[bl[u]]>dep[bl[v]])
{
if(!firstu) firstu=true,ansu=query(,,n,id[bl[u]],id[u]);
else ansu=query(,,n,id[bl[u]],id[u])+ansu;
u=fa[bl[u]];
}
else
{
if(!firstv) firstv=true,ansv=query(,,n,id[bl[v]],id[v]);
else ansv=query(,,n,id[bl[v]],id[v])+ansv;
v=fa[bl[v]];
}
}
if(dep[u]>dep[v])
{
if(!firstu) firstu=true,ansu=query(,,n,id[v],id[u]);
else ansu=query(,,n,id[v],id[u])+ansu;
}
else
{
if(!firstv) firstv=true,ansv=query(,,n,id[u],id[v]);
else ansv=query(,,n,id[u],id[v])+ansv;
}
if(!firstu) ansu=ansv;
else
{
ansu.turn();
if(firstv) ansu=ansu+ansv;
}
cout<<max(ansu.mx[][],ansu.mx[][])<<'\n';
} void change(int k,int l,int r,int x,bool u,bool v)
{
if(l==r)
{
a[l][]=u;
a[l][]=v;
if(a[l][]) tr[k].sum[][]=;
else tr[k].sum[][]=;
if(a[l][]) tr[k].sum[][]=;
else tr[k].sum[][]=;
if(a[l][] && a[l][]) tr[k].sum[][]=tr[k].sum[][]=;
else tr[k].sum[][]=tr[k].sum[][]=;
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
tr[k].mx[][]=max(tr[k].sum[][],tr[k].sum[][]);
return;
}
int mid=l+r>>;
if(x<=mid) change(k<<,l,mid,x,u,v);
else change(k<<|,mid+,r,x,u,v);
tr[k]=tr[k<<]+tr[k<<|];
} int main()
{
freopen("fight.in","r",stdin);
freopen("fight.out","w",stdout);
int m;
read(n); read(m);
int u,v;
for(int i=;i<n;++i)
{
read(u); read(v);
add(u,v);
}
dfs1();
dfs2(,);
char s[];
for(int i=;i<=n;++i)
{
scanf("%s",s);
if(s[]=='.') a[i][]=true;
if(s[]=='.') a[i][]=true;
}
build(,,n);
char c[];
while(m--)
{
scanf("%s",c);
if(c[]=='Q')
{
read(u); read(v);
Query(u,v);
}
else
{
read(u);
scanf("%s",c);
change(,,n,id[u],c[]=='.',c[]=='.');
}
}
}

bzoj千题计划243:bzoj2325: [ZJOI2011]道馆之战的更多相关文章

  1. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  2. bzoj千题计划139:bzoj2229: [Zjoi2011]最小割

    http://www.lydsy.com/JudgeOnline/problem.php?id=2229 最小割树介绍:http://blog.csdn.net/jyxjyx27/article/de ...

  3. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  4. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  5. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

  6. bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

  7. bzoj千题计划304:bzoj3676: [Apio2014]回文串(回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3676 回文自动机模板题 4年前的APIO如今竟沦为模板,,,╮(╯▽╰)╭,唉 #include& ...

  8. bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹

    http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...

  9. bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机

    http://www.lydsy.com/JudgeOnline/problem.php?id=4590 二分 这么道水题 没long long WA了两发,没判-1WA了一发,二分写错WA了一发 最 ...

随机推荐

  1. 【BZOJ2002】弹飞绵羊(Link-Cut Tree)

    [BZOJ2002]弹飞绵羊(Link-Cut Tree) 题面 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lost ...

  2. 【BZOJ1798】【AHOI2009】维护序列(线段树)

    题目链接 题解 这不就是luogu的线段树2的板子吗.... 没有任何的区别... 上代码吧... #include<iostream> #include<cstdio> #i ...

  3. Spring Boot Security 基于角色的访问控制

    @Override protected void configure(HttpSecurity http) throws Exception { //如果配置为需要登录 if (needLogin) ...

  4. Zabbix JMX监控之ActiveMQ

    监控原理: ActiveMQ作为依赖java环境的中间件,同样可以像tomcat一样用JMX(java扩展程序)监控.并且与tomcat不同的是,ActiveMQ自带了JMX,只需在配置文件中开启即可 ...

  5. Hadoop之Secondary NameNode

    NameNode存储文件系统的变化作为log追加在本地的一个文件里:这个文件是edits.当一个NameNode启动时,它从一个映像文件:FsImage,读取HDFS的状态,使用来自edits日志文件 ...

  6. CMake 条件判断

    CMake简介 CMake 是做什么的? CMake是一套类似于automake的跨平台辅助项目编译的工具. 我觉得语法更加简单易用. CMake的工作流程 CMake处理顶级目录的CMakeList ...

  7. 用jquery实现日期控件

    用jquery实现的日期控件,代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  8. java web 项目中获取当前路径的几种方法

    1.jsp中取得路径:   以工程名为TEST为例: (1)得到包含工程名的当前页面全路径:request.getRequestURI() 结果:/TEST/test.jsp (2)得到工程名:req ...

  9. 微信小程序开发之--”emplate模板“的应用

    第一步:定义模板 ①:新建一个template文件夹用来管理项目中所有的模板(本文案例定义文件夹名为:temp): ②.新建一个wxml文件来定义模板(本文案例定义文件夹名为:temp.wxml): ...

  10. IMLite轻量级即时通信工具开发指南

    花了一周时间开发了一个简单的即时通信工具,勉强算是程序原型.现在我把开发流程和一些个人的想法记录下来.本文首先介绍程序架构和通信接口,之后会聚焦到服务器的信号槽设计原则,接下来将解释有关TCP通信的粘 ...