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. [Luogu4174][NOI2006]最大获益

    luogu sol 一周没摸键盘了回来刷刷水题练练手感 显然,最大化收益可以转化为最小化损失,从而建立最小割模型. 记\(tot=\sum_{i=1}^{m}C_i\),事先假设所有的获益都得到了,那 ...

  2. 【Chrome控制台】获取元素上绑定的事件信息以及监控事件

    需求场景 在前端开发中,偶尔需要验证下某个元素上到底绑定了哪些事件,以及监控某个元素上的事件触发情况. 解决方案 普通操作 之前面对这种情况,一般采取的措施就是在各个事件里写console.info, ...

  3. Adaboost的意义

    Adaboost是广义上的提升方法(boosting method)的一个特例.广泛应用于人脸识别等领域. 它的基本思想是,“三个臭皮匠赛过诸葛亮”,即用多个弱分类器的线性加权,来得到一个强的分类器. ...

  4. 【learning】一般图最大匹配——带花树

    问题描述 ​ 对于一个图\(G(V,E)\),当点对集\(S\)满足任意\((u,v)\in S\),均有\(u,v\in V,(u,v)\in E\),且\(S\)中没有点重复出现,我们称\(S\) ...

  5. c#多线程同步之lock

    一提起lock,想必大家都很熟悉,因为它易用,顾名思义,就是一把锁,常用于多线程的同步,一次只允许一个线程进入.最近遇到一个很诡异的bug. private static readonly objec ...

  6. java容器类2:Map及HashMap深入解读

    Java的编程过程中经常会和Map打交道,现在我们来一起了解一下Map的底层实现,其中的思想结构对我们平时接口设计和编程也有一定借鉴作用.(以下接口分析都是以jdk1.8源码为参考依据) 1. Map ...

  7. kill 掉所有正在运行的hadoop jobs

    # get list of job's process IDs JOB_LIST=$(hadoop job -list 2> /dev/null | grep job_ | awk '{prin ...

  8. css 如何隐藏滚动条

    原理: 把滚动条设为完全透明: /* 设置滚动条的样式 */::-webkit-scrollbar { width: 12px;} /* 滚动槽 */::-webkit-scrollbar-track ...

  9. JWT实战:使用axios+PHP实现登录认证

    上一篇文中,我们学习了什么是JWT(Json Web Token),今天我们来结合实例给大家讲述JWT的实战应用,就是如何使用前端Axios与后端PHP实现用户登录鉴权认证的过程. 查看演示 下载源码 ...

  10. AngularJS - 常用方法汇总

    1. 数组元素的常用方法: http://www.cnblogs.com/diaosizhang/p/3729078.html 2. js的强大的splice方法  http://www.jb51.n ...